Python装饰器详解
1. 装饰器是什么?
装饰器(Decorator)是Python中用于动态修改函数或类行为的工具。它本质上是一个高阶函数,接受一个函数作为参数,返回一个新的增强函数。通过@decorator
语法糖,可以在不修改原函数代码的情况下扩展其功能。
2. 核心语法与原理
-
基本语法:
@decorator_name def target_function(): pass
等价于:
target_function = decorator_name(target_function)
-
保留元数据:
使用functools.wraps
保留原函数的名称、文档字符串等信息:import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): # 增强逻辑 return func(*args, **kwargs) return wrapper
3. 常见使用场景
装饰器广泛应用于以下场景:
场景 | 作用 | 示例代码 |
---|---|---|
日志记录 | 记录函数输入输出及执行细节 | python def log_decorator(func): ... logging.info(f"Call {func.__name__}") |
性能分析 | 测量函数执行时间 | python def timer(func): ... print(f"Time: {time.time()-start}") |
权限验证 | 检查用户权限 | python def auth_required(func): ... if not user.is_admin: raise Error |
缓存结果 | 存储函数结果避免重复计算 | python def memoize(func): ... cache[args] = func(*args) |
输入验证 | 确保参数合法性 | python def validate_input(func): ... if not isinstance(x, int): raise |
重试机制 | 自动重试失败操作 | python def retry(func): ... for _ in range(3): try: return func() |
4. 高级用法
-
带参数的装饰器:
通过嵌套函数实现参数传递:def repeat(n): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3) def greet(name): print(f"Hello { name}")
-
类装饰器:
定义__call__
方法修改类行为:class LogDecorator: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print(f"Call { self.func.__name__}") return self.func(*args, **kwargs) @LogDecorator def my_function(): pass
-
装饰器链:
组合多个装饰器,按从内到外顺序执行:@decorator1 @decorator2 def my_func(): pass
5. 实际应用示例
场景:优化斐波那契数列计算
import functools
import time
# 日志装饰器
def log_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"Call {
func.__name__} with args {
args}")
result = func(*args, **kwargs)
print(f"{
func.__name__} returned {
result}")
return result
return wrapper
# 计时装饰器
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"{
func.__name__} took {
time.time()-start:.4f}s")
return result
return wrapper
# 缓存装饰器
def memoize(func):
cache = {
}
@functools.wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
# 应用装饰器
@log_decorator
@timer
@memoize
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30)) # 输出结果并显示执行时间
6. 总结
装饰器是Python中提升代码复用性和可维护性的重要工具。通过动态增强函数行为,它适用于日志记录、性能监控、权限控制等多种场景。合理使用装饰器能使代码更简洁优雅,同时避免重复代码。