装饰器 #
装饰器是一种修改函数行为的优雅方式。
一、基本概念 #
装饰器本质上是一个函数,它接受一个函数作为参数并返回一个新函数。
python
def my_decorator(func):
def wrapper():
print("函数执行前")
func()
print("函数执行后")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后
二、带参数的装饰器 #
python
def my_decorator(func):
def wrapper(*args, **kwargs):
print("函数执行前")
result = func(*args, **kwargs)
print("函数执行后")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
print(add(3, 5)) # 输出:函数执行前, 函数执行后, 8
三、保留函数元信息 #
python
from functools import wraps
def my_decorator(func):
@wraps(func) # 保留原函数的元信息
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@my_decorator
def greet(name):
"""问候函数"""
print(f"Hello, {name}!")
print(greet.__name__) # "greet"(不是"wrapper")
print(greet.__doc__) # "问候函数"
四、带参数的装饰器 #
python
def repeat(times):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(times=3)
def say_hello():
print("Hello!")
say_hello() # 输出3次Hello!
五、常见应用场景 #
5.1 计时装饰器 #
python
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行时间:{end - start:.4f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "完成"
slow_function() # slow_function 执行时间:1.0001秒
5.2 日志装饰器 #
python
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__},参数:{args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} 返回:{result}")
return result
return wrapper
@log
def add(a, b):
return a + b
add(3, 5)
5.3 缓存装饰器 #
python
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(50)) # 快速计算
5.4 权限检查 #
python
def require_login(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not is_logged_in():
raise PermissionError("请先登录")
return func(*args, **kwargs)
return wrapper
@require_login
def get_user_data():
return "敏感数据"
六、类装饰器 #
python
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"第{self.count}次调用")
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello!")
say_hello() # 第1次调用
say_hello() # 第2次调用
七、多个装饰器 #
python
@decorator1
@decorator2
def func():
pass
# 等价于
func = decorator1(decorator2(func))
八、总结 #
| 概念 | 说明 |
|---|---|
| 本质 | 接受函数返回函数的函数 |
| 语法 | @decorator |
| 参数 | 使用*args, **kwargs |
| 元信息 | 使用@wraps(func)保留 |
| 带参数 | 多层嵌套函数 |
最后更新:2026-03-16