Python装饰器深入解析从基础到高级应用引言装饰器是Python中非常强大的特性允许我们在不修改函数代码的情况下扩展其功能。作为从Python转向Rust的后端开发者我发现装饰器是Python中最具特色的功能之一广泛应用于日志记录、性能监控、权限验证等场景。本文将深入探讨装饰器的原理和最佳实践。一、装饰器基础1.1 什么是装饰器装饰器是一种设计模式用于包装函数或类在不修改其源代码的情况下扩展功能。def my_decorator(func): def wrapper(): print(Before function) func() print(After function) return wrapper my_decorator def say_hello(): print(Hello!) say_hello()1.2 装饰器语法# 装饰器应用 decorator def function(): pass # 等价于 function decorator(function)1.3 带参数的装饰器def repeat(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): result func(*args, **kwargs) return result return wrapper return decorator repeat(times3) def greet(name): print(fHello, {name}!) greet(Alice)二、高级装饰器2.1 保留函数元数据import functools def my_decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper my_decorator def example(): This is a docstring pass print(example.__name__) # example print(example.__doc__) # This is a docstring2.2 类装饰器class CountCalls: def __init__(self, func): self.func func self.count 0 def __call__(self, *args, **kwargs): self.count 1 print(fCall {self.count} of {self.func.__name__}) return self.func(*args, **kwargs) CountCalls def say_hello(): print(Hello!) say_hello() # Call 1 of say_hello; Hello! say_hello() # Call 2 of say_hello; Hello!2.3 多个装饰器def decorator1(func): def wrapper(*args, **kwargs): print(Decorator 1 before) result func(*args, **kwargs) print(Decorator 1 after) return result return wrapper def decorator2(func): def wrapper(*args, **kwargs): print(Decorator 2 before) result func(*args, **kwargs) print(Decorator 2 after) return result return wrapper decorator1 decorator2 def greet(): print(Hello!) # 执行顺序decorator1(decorator2(greet)) greet()三、装饰器实战3.1 日志记录import logging logging.basicConfig(levellogging.INFO) def log_function(func): functools.wraps(func) def wrapper(*args, **kwargs): logging.info(fCalling {func.__name__} with args: {args}, kwargs: {kwargs}) try: result func(*args, **kwargs) logging.info(f{func.__name__} returned: {result}) return result except Exception as e: logging.error(f{func.__name__} raised {type(e).__name__}: {e}) raise return wrapper log_function def add(a, b): return a b3.2 性能监控import time def timeit(func): functools.wraps(func) def wrapper(*args, **kwargs): start time.time() result func(*args, **kwargs) elapsed time.time() - start print(f{func.__name__} took {elapsed:.4f} seconds) return result return wrapper timeit def slow_function(): time.sleep(1) return Done3.3 权限验证def require_permission(permission): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): current_user get_current_user() if permission not in current_user.permissions: raise PermissionError(fPermission {permission} required) return func(*args, **kwargs) return wrapper return decorator require_permission(admin) def delete_user(user_id): # 删除用户逻辑 pass四、装饰器设计模式4.1 工厂模式def create_validator(validation_func): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): if not validation_func(*args, **kwargs): raise ValueError(Validation failed) return func(*args, **kwargs) return wrapper return decorator def is_positive(*args): return all(arg 0 for arg in args) create_validator(is_positive) def divide(a, b): return a / b4.2 观察者模式def event_handler(event_name): def decorator(func): register_event_handler(event_name, func) return func return decorator event_handler(user_created) def send_welcome_email(user): print(fSending welcome email to {user.email})4.3 策略模式def strategy(name): def decorator(func): register_strategy(name, func) return func return decorator strategy(quick_sort) def quick_sort(arr): # 快速排序实现 pass strategy(merge_sort) def merge_sort(arr): # 归并排序实现 pass五、装饰器最佳实践5.1 保持装饰器简洁# 不好装饰器过于复杂 def complex_decorator(func): def wrapper(*args, **kwargs): # 大量逻辑... if condition1: # 处理... elif condition2: # 处理... return func(*args, **kwargs) return wrapper # 好将逻辑分离到单独函数 def validate_input(args): # 验证逻辑 pass def log_call(func): functools.wraps(func) def wrapper(*args, **kwargs): validate_input(args) return func(*args, **kwargs) return wrapper5.2 使用类装饰器管理状态class Cached: def __init__(self, func): self.func func self.cache {} def __call__(self, *args): if args not in self.cache: self.cache[args] self.func(*args) return self.cache[args] Cached def expensive_computation(n): # 耗时计算 return n * n5.3 避免过度使用装饰器# 不好装饰器过多难以理解 decorator1 decorator2 decorator3 decorator4 def my_function(): pass # 好合并相关装饰器 def combined_decorator(func): return decorator1(decorator2(decorator3(func))) combined_decorator def my_function(): pass六、内置装饰器6.1 staticmethodclass MyClass: staticmethod def helper(): return Helper method # 不需要实例化 MyClass.helper()6.2 classmethodclass MyClass: instance_count 0 def __init__(self): MyClass.instance_count 1 classmethod def get_instance_count(cls): return cls.instance_count6.3 propertyclass Person: def __init__(self, name): self._name name property def name(self): return self._name name.setter def name(self, value): if not value: raise ValueError(Name cannot be empty) self._name value七、总结装饰器是Python中非常强大的特性通过合理使用可以提高代码的可读性和可维护性。关键要点使用functools.wraps保留函数元数据保持装饰器简洁避免过于复杂的逻辑类装饰器适合需要管理状态的场景组合装饰器合并相关功能内置装饰器staticmethod、classmethod、property从Python转向Rust后我发现Rust的宏系统可以实现类似装饰器的功能但语法和使用方式有所不同。延伸阅读Python装饰器官方文档functools模块文档《Python Cookbook》装饰器章节Python装饰器设计模式