目录

装饰器
装饰器是Python中最优雅的特性之一,它体现了"开放-封闭原则"的精髓:对扩展开放,对修改封闭。在企业级应用中,如Flask的路由装饰器到Django的权限装饰器、缓存、日志、性能监控、事务管理。
应用实例
# 在微服务架构中,装饰器承担着重要角色
@app.route('/api/users/<int:user_id>')
@require_auth
@rate_limit(requests_per_minute=100)
@cache(expire=300)
@monitor_performance
@log_request
def get_user(user_id):
return User.objects.get(id=user_id)
# 这个简单的函数通过装饰器获得了:
# - 路由映射
# - 身份验证
# - 限流保护
# - 缓存加速
装饰器的高级用法与内部机制
装饰器的执行时机与作用域
import functools
import time
class DecoratorInternals:
"""装饰器内部机制深度解析"""
@staticmethod
def execution_timing_demo():
"""演示装饰器的执行时机"""
print("=== 装饰器执行时机演示 ===")
# 装饰器在模块导入时执行
def timing_decorator(func):
print(f" 装饰器正在装饰函数: {func.__name__}") # 模块导入时执行!
@functools.wraps(func) # 核心魔法:复制元数据
def wrapper(*args, **kwargs):
print(f" 执行函数: {func.__name__}") # 函数调用时执行!
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f" 函数 {func.__name__} 执行时间: {end_time - start_time:.4f}秒")
return result
print(f" 函数 {func.__name__} 装饰完成")
return wrapper
print("开始定义函数...")
@timing_decorator
def slow_function():
"""一个慢函数"""
time.sleep(0.1)
return "完成"
print("函数定义完成,开始调用...")
result = slow_function()
print(f"函数返回: {result}")
return slow_function
@staticmethod
def scope_and_closure_demo():
print("\n=== 装饰器作用域和闭包演示 ===")
def create_counter_decorator():
"""创建计数器装饰器工厂"""
call_count = 0 # 闭包变量
def counter_decorator(func):
nonlocal call_count
@functools.wraps(func)
def wrapper(*args, **kwargs):
nonlocal call_count
call_count += 1
print(f" 函数 {func.__name__} 第 {call_count} 次调用")
return func(*args, **kwargs)
# 为wrapper添加获取计数的方法
wrapper.get_call_count = lambda: call_count
wrapper.reset_count = lambda: setattr(wrapper, '__closure__',
tuple([type(c)(0) if hasattr(c, 'cell_contents') else c
for c in wrapper.__closure__]))
return wrapper
return counter_decorator
# 创建装饰器实例
counter = create_counter_decorator()
@counter
def greet(name):
return f"Hello, {name}!"
# 测试调用
print(greet("Alice"))
print(greet("Bob"))
print(greet("Charlie"))
print(f"总调用次数: {greet.get_call_count()}")
return greet
@staticmethod
def decorator_metadata_preservation():
print("\n=== 装饰器元数据保存演示 ===")
def metadata_preserving_decorator(func):
"""保存元数据的装饰器"""
@functools.wraps(func) # 关键:保存原函数的元数据
def wrapper(*args, **kwargs):
print(f" 调用函数: {func.__name__}")
return func(*args, **kwargs)
# 保存额外的元数据
wrapper.__wrapped__ = func # 保存原函数引用
wrapper.__decorator__ = 'metadata_preserving_decorator'
return wrapper
@metadata_preserving_decorator
def documented_function(x: int, y: int) -> int:
"""
这是一个有详细文档的函数
Args:
x: 第一个整数
y: 第二个整数
Returns:
两个整数的和
"""
return x + y
# 检查元数据是否保存
print(f"函数名: {documented_function.__name__}")
print(f"文档字符串: {documented_function.__doc__}")
print(f"类型注解: {documented_function.__annotations__}")
print(f"原函数: {documented_function.__wrapped__}")
print(f"装饰器标识: {documented_function.__decorator__}")
# 测试函数
result = documented_function(3, 5)
print(f"计算结果: {result}")
return documented_function
def test_decorator_internals():
"""测试装饰器内部机制"""
internals = DecoratorInternals()
# 测试执行时机
slow_func = internals.execution_timing_demo()
# 测试作用域和闭包
greet_func = internals.scope_and_closure_demo()
# 测试元数据保存
doc_func = internals.decorator_metadata_preservation()
test_decorator_internals()
装饰器执行时机:模块导入时的魔法
装饰阶段:在模块导入时立即执行,完成函数的包装;调用阶段:在函数实际调用时执行wrapper逻辑;返回阶段:返回装饰后的函数对象。
作用域与闭包:装饰器的记忆能力
作用域层次:全局作用域:create_counter_decorator函数;闭包作用域:call_count变量(被内部函数记住);局部作用域:wrapper函数内部的变量
闭包的优势:状态保持:在多次调用间保持状态;数据封装:避免全局变量污染;灵活性:每个装饰器实例有独立状态。
元数据保存:functools.wraps的魔力
| 元数据类型 | 说明 | 重要性 |
|---|---|---|
__name__ | 函数名 | 调试和日志 |
__doc__ | 文档字符串 | 帮助文档 |
__annotations__ | 类型注解 | 类型检查 |
__module__ | 模块名 | 导入系统 |
高级装饰器模式
import functools
import time
class AdvancedDecoratorPatterns:
"""高级装饰器模式"""
class ParameterizedDecorator:
"""参数化装饰器基类"""
def __init__(self, **config):
self.config = config
def __call__(self, func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return self._execute(func, args, kwargs)
# 保存配置信息
wrapper._decorator_config = self.config
return wrapper
def _execute(self, func, args, kwargs):
"""子类需要实现的执行逻辑"""
return func(*args, **kwargs)
class RetryDecorator(ParameterizedDecorator):
"""重试装饰器"""
def __init__(self, max_attempts=3, delay=1.0, backoff=2.0,
exceptions=(Exception,)):
super().__init__(
max_attempts=max_attempts,
delay=delay,
backoff=backoff,
exceptions=exceptions
)
def _execute(self, func, args, kwargs):
last_exception = None
current_delay = self.config['delay']
for attempt in range(self.config['max_attempts']):
try:
return func(*args, **kwargs)
except self.config['exceptions'] as e:
last_exception = e
if attempt < self.config['max_attempts'] - 1:
print(f" 重试 {func.__name__} (第{attempt + 1}次失败): {e}")
time.sleep(current_delay)
current_delay *= self.config['backoff']
else:
print(f" {func.__name__} 重试失败,已达最大次数")
raise last_exception
class CircuitBreakerDecorator(ParameterizedDecorator):
"""熔断器装饰器"""
def __init__(self, failure_threshold=5, recovery_timeout=60,
expected_exception=Exception):
super().__init__(
failure_threshold=failure_threshold,
recovery_timeout=recovery_timeout,
expected_exception=expected_exception
)
self.failure_count = 0
self.last_failure_time = None
self.state = 'CLOSED' # CLOSED, OPEN, HALF_OPEN
def _execute(self, func, args, kwargs):
if self.state == 'OPEN':
if self._should_attempt_reset():
self.state = 'HALF_OPEN'
else:
raise Exception(f"熔断器开启,拒绝调用 {func.__name__}")
try:
result = func(*args, **kwargs)
self._on_success()
return result
except self.config['expected_exception'] as e:
self._on_failure()
raise e
def _should_attempt_reset(self):
return (time.time() - self.last_failure_time >
self.config['recovery_timeout'])
def _on_success(self):
self.failure_count = 0
self.state = 'CLOSED'
def _on_failure(self):
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.config['failure_threshold']:
self.state = 'OPEN'
print(f" 熔断器开启,失败次数: {self.failure_count}")
class AsyncDecorator:
"""异步装饰器"""
def __init__(self, timeout=None):
self.timeout = timeout
def __call__(self, func):
if not asyncio.iscoroutinefunction(func):
# 将同步函数转换为异步
@functools.wraps(func)
async def async_wrapper(*args, **kwargs):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, func, *args, **kwargs)
return async_wrapper
else:
# 为异步函数添加超时控制
@functools.wraps(func)
async def timeout_wrapper(*args, **kwargs):
if self.timeout:
return await asyncio.wait_for(func(*args, **kwargs),
timeout=self.timeout)
return await func(*args, **kwargs)
return timeout_wrapper
class ConditionalDecorator:
"""条件装饰器"""
def __init__(self, condition):
self.condition = condition
def __call__(self, decorator):
def conditional_decorator(func):
if self.condition():
return decorator(func)
return func
return conditional_decorator
def test_advanced_decorator_patterns():
"""测试高级装饰器模式"""
print("=== 高级装饰器模式测试 ===")
# 测试重试装饰器
print("\n1. 重试装饰器测试:")
@AdvancedDecoratorPatterns.RetryDecorator(max_attempts=3, delay=0.1)
def unreliable_function():
import random
if random.random() < 0.7: # 70%的失败率
raise ValueError("随机失败")
return "成功!"
try:
result = unreliable_function()
print(f"结果: {result}")
except Exception as e:
print(f"最终失败: {e}")
# 测试熔断器装饰器
print("\n2. 熔断器装饰器测试:")
circuit_breaker = AdvancedDecoratorPatterns.CircuitBreakerDecorator(
failure_threshold=3, recovery_timeout=2
)
@circuit_breaker
def failing_service():
raise ConnectionError("服务不可用")
# 触发熔断器
for i in range(5):
try:
failing_service()
except Exception as e:
print(f"第{i+1}次调用失败: {e}")
# 测试条件装饰器
print("\n3. 条件装饰器测试:")
DEBUG = True
@AdvancedDecoratorPatterns.ConditionalDecorator(lambda: DEBUG)
def debug_decorator(func):
@functools.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
@debug_decorator
def calculate(x, y):
return x + y
result = calculate(3, 5)
print(f"计算结果: {result}")
# 需要导入asyncio用于异步装饰器
import asyncio
test_advanced_decorator_patterns()
1、参数化装饰器基类(ParameterizedDecorator)
设计思路:通过基类封装参数传递和装饰器调用逻辑,子类只需实现具体执行逻辑 _execute。
实现细节:__init__ 接收配置参数,保存到 self.config。__call__ 返回包装函数 wrapper,调用 _execute 执行具体逻辑。方便扩展,减少重复代码。
2、重试装饰器(RetryDecorator)
功能:对可能失败的函数自动重试,支持最大尝试次数、延迟、指数退避和异常类型过滤。
实现要点:继承自 ParameterizedDecorator,重写 _execute。捕获指定异常,失败时等待并重试。超过最大重试次数后抛出最后异常。应用场景:网络请求、IO操作等不稳定任务。
3、熔断器装饰器(CircuitBreakerDecorator)
功能:防止系统因连续失败而崩溃,达到失败阈值后“断路”,拒绝调用等待恢复超时后尝试恢复。
实现要点:维护失败计数、状态(CLOSED、OPEN、HALF_OPEN)和最后失败时间。调用失败时增加失败计数,超过阈值切换到 OPEN 状态。OPEN 状态等待超时后进入 HALF_OPEN,尝试调用成功则恢复 CLOSED。应用场景:微服务调用、分布式系统容错。
4、异步装饰器(AsyncDecorator)
功能:支持同步函数异步化,或为异步函数添加超时控制。实现要点:判断被装饰函数是否为协程函数。同步函数通过 loop.run_in_executor 转为异步执行。异步函数通过 asyncio.wait_for 实现超时。应用场景:异步编程、协程任务管理。
5、条件装饰器(ConditionalDecorator)
功能:根据条件动态决定是否应用某个装饰器。实现要点:接收一个无参函数 condition返回布尔值。只有条件为真时才应用传入的装饰器,否则返回原函数。应用场景:调试日志、功能开关等。
装饰器性能优化
import cProfile
import pstats
import io
import functools
import time
import weakref
class DecoratorPerformanceOptimization:
"""装饰器性能优化"""
@staticmethod
def benchmark_decorator_overhead():
print("=== 装饰器性能开销测试 ===")
def simple_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def optimized_decorator(func):
"""优化的装饰器,减少函数调用开销"""
# 预先获取函数引用,避免每次查找
original_func = func
@functools.wraps(func)
def wrapper(*args, **kwargs):
return original_func(*args, **kwargs)
return wrapper
def no_wrapper_decorator(func):
"""无包装器的装饰器(适用于某些场景)"""
# 直接返回原函数,只添加属性
func._decorated = True
return func
def test_function(x):
return x * 2
# 创建不同版本的装饰函数
simple_decorated = simple_decorator(test_function)
optimized_decorated = optimized_decorator(test_function)
no_wrapper_decorated = no_wrapper_decorator(test_function)
iterations = 1000000 # 性能测试
start_time = time.time() # 测试原函数
for i in range(iterations):
test_function(i)
original_time = time.time() - start_time
start_time = time.time() # 测试简单装饰器
for i in range(iterations):
simple_decorated(i)
simple_time = time.time() - start_time
start_time = time.time() # 测试优化装饰器
for i in range(iterations):
optimized_decorated(i)
optimized_time = time.time() - start_time
# 测试无包装器装饰器
start_time = time.time()
for i in range(iterations):
no_wrapper_decorated(i)
no_wrapper_time = time.time() - start_time
print(f"原函数时间: {original_time:.4f}秒")
print(f"简单装饰器时间: {simple_time:.4f}秒 (开销: {((simple_time/original_time-1)*100):.1f}%)")
print(f"优化装饰器时间: {optimized_time:.4f}秒 (开销: {((optimized_time/original_time-1)*100):.1f}%)")
print(f"无包装器时间: {no_wrapper_time:.4f}秒 (开销: {((no_wrapper_time/original_time-1)*100):.1f}%)")
class HighPerformanceDecorator:
"""高性能装饰器实现"""
def __init__(self, enable_cache=True, cache_size=128):
self.enable_cache = enable_cache
self.cache_size = cache_size
self._cache = {}
self._stats = {'hits': 0, 'misses': 0, 'calls': 0}
def __call__(self, func):
if self.enable_cache:
return self._create_cached_wrapper(func)
else:
return self._create_simple_wrapper(func)
def _create_cached_wrapper(self, func):
"""创建带缓存的包装器"""
cache = {}
cache_info = {'hits': 0, 'misses': 0, 'maxsize': self.cache_size}
@functools.wraps(func)
def cached_wrapper(*args, **kwargs):
# 创建缓存键
key = self._make_key(args, kwargs)
if key in cache:
cache_info['hits'] += 1
return cache[key]
# 缓存未命中
cache_info['misses'] += 1
result = func(*args, **kwargs)
# 缓存管理
if len(cache) >= self.cache_size:
# LRU淘汰策略:删除最旧的条目
oldest_key = next(iter(cache))
del cache[oldest_key]
cache[key] = result
return result
# 添加缓存信息方法
cached_wrapper.cache_info = lambda: cache_info.copy()
cached_wrapper.cache_clear = lambda: cache.clear()
return cached_wrapper
def _create_simple_wrapper(self, func):
"""创建简单包装器"""
@functools.wraps(func)
def simple_wrapper(*args, **kwargs):
self._stats['calls'] += 1
return func(*args, **kwargs)
simple_wrapper.get_stats = lambda: self._stats.copy()
return simple_wrapper
def _make_key(self, args, kwargs):
"""创建缓存键"""
key = args
if kwargs:
key += tuple(sorted(kwargs.items()))
return key
class WeakRefDecorator:
"""使用弱引用的装饰器,避免内存泄漏"""
def __init__(self):
self._instances = weakref.WeakKeyDictionary()
def __call__(self, func):
@functools.wraps(func)
def wrapper(instance, *args, **kwargs):
# 使用弱引用存储实例调用统计
if instance not in self._instances:
self._instances[instance] = {'call_count': 0}
self._instances[instance]['call_count'] += 1
return func(instance, *args, **kwargs)
wrapper.get_instance_stats = lambda: {str(k): v for k, v in self._instances.items()}
return wrapper
@staticmethod
def profile_decorator_performance():
print("\n=== 装饰器性能分析 ===")
profiler = cProfile.Profile() # 创建性能分析器
# 高性能装饰器
high_perf = DecoratorPerformanceOptimization.HighPerformanceDecorator(
enable_cache=True, cache_size=100
)
@high_perf
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
profiler.enable() # 开始性能分析
for i in range(10): # 执行测试
result = fibonacci(20)
profiler.disable()
# 输出性能报告
s = io.StringIO()
ps = pstats.Stats(profiler, stream=s).sort_stats('cumulative')
ps.print_stats(10) # 显示前10个最耗时的函数
print("性能分析报告:")
print(s.getvalue())
# 显示缓存统计
cache_info = fibonacci.cache_info()
print(f"缓存统计: {cache_info}")
def test_performance_optimization():
"""测试性能优化"""
DecoratorPerformanceOptimization.benchmark_decorator_overhead() # 基准测试
DecoratorPerformanceOptimization.profile_decorator_performance() # 性能分析
# 测试弱引用装饰器
print("\n=== 弱引用装饰器测试 ===")
weak_decorator = DecoratorPerformanceOptimization.WeakRefDecorator()
class TestClass:
def __init__(self, name):
self.name = name
@weak_decorator
def method(self):
return f"test_{self.name}"
# 创建实例并调用方法
obj1 = TestClass("obj1")
obj2 = TestClass("obj2")
obj1.method()
obj1.method()
obj2.method()
print(f"实例统计: {weak_decorator._instances.keyrefs()}")
# 删除实例,测试弱引用
del obj1
import gc
gc.collect()
print("删除obj1后的统计:")
for ref in weak_decorator._instances.keyrefs():
obj = ref()
if obj:
print(f" {obj.name}: {weak_decorator._instances[obj]}")
else:
print(" 对象已被垃圾回收")
if __name__ == "__main__":
test_performance_optimization()
简单装饰器:标准的装饰器实现,使用functools.wraps保留元数据
优化装饰器:预先获取函数引用,减少每次调用的查找开销
无包装器装饰器:直接修改原函数,不创建包装函数
测试结果显示,即使是简单装饰器也会带来约5-10%的性能开销,而无包装器装饰器几乎零开销(但功能受限)。这段代码实现了高性能装饰器类,支持以下特性: 可选的缓存机制:通过LRU缓存减少重复计算;缓存统计:跟踪缓存命中率和调用次数;灵活的配置:可调整缓存大小和启用/禁用缓存。
类装饰器与函数装饰器
import functools
import time
class ClassVsFunctionDecorators:
"""类装饰器与函数装饰器对比"""
class StatefulDecorator:
"""有状态的类装饰器"""
def __init__(self, prefix="", track_calls=True):
self.prefix = prefix
self.track_calls = track_calls
self.call_history = []
self.call_count = 0
def __call__(self, func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
self.call_count += 1
call_info = {
'function': func.__name__,
'args': args,
'kwargs': kwargs,
'timestamp': time.time(),
'call_number': self.call_count
}
if self.track_calls:
self.call_history.append(call_info)
print(f"{self.prefix}[{self.call_count}] 调用 {func.__name__}")
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
call_info['duration'] = end_time - start_time
call_info['result'] = result
return result
# 为包装器添加访问装饰器状态的方法
wrapper.get_call_count = lambda: self.call_count
wrapper.get_call_history = lambda: self.call_history.copy()
wrapper.reset_stats = self.reset_stats
return wrapper
def reset_stats(self):
"""重置统计信息"""
self.call_count = 0
self.call_history.clear()
class ConfigurableValidator:
"""可配置的验证装饰器"""
def __init__(self, **validators):
self.validators = validators
def __call__(self, func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# 获取函数签名
import inspect
sig = inspect.signature(func)
bound_args = sig.bind(*args, **kwargs)
bound_args.apply_defaults()
# 执行验证
for param_name, value in bound_args.arguments.items():
if param_name in self.validators:
validator = self.validators[param_name]
if not validator(value):
raise ValueError(f"参数 {param_name} 验证失败: {value}")
return func(*args, **kwargs)
return wrapper
class ContextManagerDecorator:
"""上下文管理器装饰器"""
def __init__(self, setup_func=None, teardown_func=None):
self.setup_func = setup_func
self.teardown_func = teardown_func
self.context_data = {}
def __call__(self, func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# 设置阶段
if self.setup_func:
self.context_data = self.setup_func() or {}
try:
# 将上下文数据传递给函数
if 'context' in func.__code__.co_varnames:
kwargs['context'] = self.context_data
result = func(*args, **kwargs)
return result
finally:
# 清理阶段
if self.teardown_func:
self.teardown_func(self.context_data)
return wrapper
@staticmethod
def function_decorator_equivalent():
"""函数装饰器的等价实现"""
def stateful_function_decorator(prefix="", track_calls=True):
# 使用闭包保存状态
call_history = []
call_count = 0
def decorator(func):
nonlocal call_count, call_history
@functools.wraps(func)
def wrapper(*args, **kwargs):
nonlocal call_count
call_count += 1
call_info = {
'function': func.__name__,
'args': args,
'kwargs': kwargs,
'timestamp': time.time(),
'call_number': call_count
}
if track_calls:
call_history.append(call_info)
print(f"{prefix}[{call_count}] 调用 {func.__name__}")
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
call_info['duration'] = end_time - start_time
call_info['result'] = result
return result
# 添加访问状态的方法
wrapper.get_call_count = lambda: call_count
wrapper.get_call_history = lambda: call_history.copy()
def reset_stats():
nonlocal call_count, call_history
call_count = 0
call_history.clear()
wrapper.reset_stats = reset_stats
return wrapper
return decorator
return stateful_function_decorator
def test_class_vs_function_decorators():
print("=== 类装饰器与函数装饰器对比 ===")
# 测试类装饰器
print("\n1. 类装饰器测试:")
class_decorator = ClassVsFunctionDecorators.StatefulDecorator(
prefix="CLASS", track_calls=True
)
@class_decorator
def test_function_class(x, y):
return x + y
# 调用函数
result1 = test_function_class(1, 2)
result2 = test_function_class(3, 4)
print(f"调用次数: {test_function_class.get_call_count()}")
print(f"调用历史: {len(test_function_class.get_call_history())} 条记录")
# 测试函数装饰器
print("\n2. 函数装饰器测试:")
function_decorator = ClassVsFunctionDecorators.function_decorator_equivalent()(
prefix="FUNC", track_calls=True
)
@function_decorator
def test_function_func(x, y):
return x * y
# 调用函数
result3 = test_function_func(2, 3)
result4 = test_function_func(4, 5)
print(f"调用次数: {test_function_func.get_call_count()}")
print(f"调用历史: {len(test_function_func.get_call_history())} 条记录")
# 测试验证装饰器
print("\n3. 验证装饰器测试:")
@ClassVsFunctionDecorators.ConfigurableValidator(
x=lambda v: isinstance(v, int) and v > 0,
y=lambda v: isinstance(v, str) and len(v) > 0
)
def validated_function(x, y):
return f"{y} * {x} = {y * x}"
try:
result = validated_function(5, "Hello")
print(f"验证通过: {result}")
except ValueError as e:
print(f"验证失败: {e}")
try:
result = validated_function(-1, "Hello") # 应该失败
except ValueError as e:
print(f"验证失败: {e}")
# 测试上下文管理器装饰器
print("\n4. 上下文管理器装饰器测试:")
def setup():
print(" 设置资源")
return {'database': 'connected', 'cache': 'initialized'}
def teardown(context):
print(f" 清理资源: {context}")
@ClassVsFunctionDecorators.ContextManagerDecorator(setup, teardown)
def process_data(data, context=None):
print(f" 处理数据: {data}")
print(f" 上下文: {context}")
return f"processed: {data}"
result = process_data("test data")
print(f"结果: {result}")
test_class_vs_function_decorators()
类装饰器在初始化时需要创建类实例,有轻微开销;类装饰器占用稍多内存,但提供了更好的状态管理
使用类装饰器的场景:需要复杂状态管理:如调用统计、缓存管理;需要配置选项:如验证规则、超时设置;需要资源管理:如数据库连接、文件操作;需要继承和扩展:创建装饰器家族’
使用函数装饰器的场景:简单无状态装饰:如日志记录、计时;快速原型开发:代码更简洁;轻量级修改:如添加属性、修改返回值
实践总结:保持一致性:在项目中统一使用类或函数装饰器风格;使用functools.wraps:保持被装饰函数的元信息;考虑可测试性:类装饰器通常更容易单元测试;文档化装饰器:明确说明装饰器的功能和使用方法;性能敏感场景:在循环中调用的函数避免使用复杂装饰器;
装饰器在设计模式中的应用
import functools,time
class DecoratorDesignPatterns:
"""装饰器在设计模式中的应用"""
# 1. 单例模式
class Singleton:
"""单例模式装饰器"""
def __init__(self, cls):
self._cls = cls
self._instances = {}
self._lock = threading.Lock()
def __call__(self, *args, **kwargs):
if self._cls not in self._instances:
with self._lock:
if self._cls not in self._instances:
self._instances[self._cls] = self._cls(*args, **kwargs)
return self._instances[self._cls]
def __getattr__(self, name):
return getattr(self._cls, name)
# 2. 观察者模式
class Observable:
"""观察者模式装饰器"""
def __init__(self, func):
self.func = func
self.observers = []
functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs):
# 执行前通知
for observer in self.observers:
observer.before_call(self.func.__name__, args, kwargs)
# 执行函数
result = self.func(*args, **kwargs)
# 执行后通知
for observer in self.observers:
observer.after_call(self.func.__name__, args, kwargs, result)
return result
def add_observer(self, observer):
"""添加观察者"""
self.observers.append(observer)
def remove_observer(self, observer):
"""移除观察者"""
if observer in self.observers:
self.observers.remove(observer)
class Observer:
"""观察者基类"""
def before_call(self, func_name, args, kwargs):
pass
def after_call(self, func_name, args, kwargs, result):
pass
class LoggingObserver(Observer):
"""日志观察者"""
def before_call(self, func_name, args, kwargs):
print(f" 即将调用 {func_name}")
def after_call(self, func_name, args, kwargs, result):
print(f" {func_name} 调用完成,结果: {result}")
class MetricsObserver(Observer):
"""指标观察者"""
def __init__(self):
self.call_count = 0
self.total_time = 0
self.start_time = None
def before_call(self, func_name, args, kwargs):
self.start_time = time.time()
def after_call(self, func_name, args, kwargs, result):
if self.start_time:
duration = time.time() - self.start_time
self.total_time += duration
self.call_count += 1
print(f" {func_name} 调用统计: 次数={self.call_count}, 平均时间={self.total_time/self.call_count:.4f}秒")
# 3. 策略模式
class Strategy:
"""策略模式装饰器"""
def __init__(self):
self.strategies = {}
def register(self, name):
"""注册策略"""
def decorator(func):
self.strategies[name] = func
return func
return decorator
def execute(self, strategy_name, *args, **kwargs):
"""执行策略"""
if strategy_name not in self.strategies:
raise ValueError(f"未知策略: {strategy_name}")
strategy = self.strategies[strategy_name]
return strategy(*args, **kwargs)
def list_strategies(self):
"""列出所有策略"""
return list(self.strategies.keys())
# 4. 命令模式
class Command:
"""命令模式装饰器"""
def __init__(self, func):
self.func = func
self.history = []
functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs):
# 创建命令对象
command = {
'function': self.func,
'args': args,
'kwargs': kwargs,
'timestamp': time.time(),
'executed': False,
'result': None
}
# 执行命令
try:
result = self.func(*args, **kwargs)
command['executed'] = True
command['result'] = result
self.history.append(command)
return result
except Exception as e:
command['error'] = str(e)
self.history.append(command)
raise
def get_history(self):
"""获取命令历史"""
return self.history.copy()
def undo_last(self):
"""撤销最后一个命令(简化实现)"""
if self.history:
last_command = self.history[-1]
print(f"🔄 撤销命令: {last_command['function'].__name__}")
# 实际实现中需要根据具体业务逻辑来撤销
return last_command
return None
# 5. 装饰器模式(递归装饰)
class DecoratorPattern:
"""装饰器模式的装饰器实现"""
def __init__(self, component):
self.component = component
def __call__(self, *args, **kwargs):
return self.component(*args, **kwargs)
class LoggingDecorator(DecoratorPattern):
"""日志装饰器"""
def __call__(self, *args, **kwargs):
print(f" 开始执行")
result = super().__call__(*args, **kwargs)
print(f" 执行完成")
return result
class TimingDecorator(DecoratorPattern):
"""计时装饰器"""
def __call__(self, *args, **kwargs):
start_time = time.time()
result = super().__call__(*args, **kwargs)
end_time = time.time()
print(f" 执行时间: {end_time - start_time:.4f}秒")
return result
import threading
def test_decorator_design_patterns():
print("=== 装饰器设计模式测试 ===")
# 测试单例模式
print("\n1. 单例模式测试:")
@DecoratorDesignPatterns.Singleton
class DatabaseConnection:
def __init__(self):
self.connection_id = id(self)
print(f"创建数据库连接: {self.connection_id}")
def query(self, sql):
return f"执行查询: {sql}"
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(f"db1 is db2: {db1 is db2}")
print(f"查询结果: {db1.query('SELECT * FROM users')}")
# 测试观察者模式
print("\n2. 观察者模式测试:")
@DecoratorDesignPatterns.Observable
def business_operation(data):
"""业务操作"""
return f"处理数据: {data}"
# 添加观察者
logging_observer = DecoratorDesignPatterns.LoggingObserver()
metrics_observer = DecoratorDesignPatterns.MetricsObserver()
business_operation.add_observer(logging_observer)
business_operation.add_observer(metrics_observer)
# 执行操作
result = business_operation("test data")
result = business_operation("more data")
# 测试策略模式
print("\n3. 策略模式测试:")
payment_strategy = DecoratorDesignPatterns.Strategy()
@payment_strategy.register("credit_card")
def credit_card_payment(amount):
return f"信用卡支付: ${amount}"
@payment_strategy.register("paypal")
def paypal_payment(amount):
return f"PayPal支付: ${amount}"
@payment_strategy.register("bank_transfer")
def bank_transfer_payment(amount):
return f"银行转账: ${amount}"
# 使用不同策略
print(f"可用策略: {payment_strategy.list_strategies()}")
print(payment_strategy.execute("credit_card", 100))
print(payment_strategy.execute("paypal", 50))
# 测试命令模式
print("\n4. 命令模式测试:")
@DecoratorDesignPatterns.Command
def file_operation(action, filename):
"""文件操作命令"""
return f"{action} 文件: {filename}"
# 执行命令
file_operation("create", "test.txt")
file_operation("edit", "test.txt")
file_operation("delete", "test.txt")
# 查看命令历史
history = file_operation.get_history()
print(f"命令历史: {len(history)} 条")
for cmd in history:
print(f" - {cmd['function'].__name__}: {cmd['args']}")
# 测试装饰器模式
print("\n5. 装饰器模式测试:")
def base_function(data):
return f"处理: {data}"
# 组合多个装饰器
decorated_func = DecoratorDesignPatterns.TimingDecorator(
DecoratorDesignPatterns.LoggingDecorator(base_function)
)
result = decorated_func("test data")
print(f"最终结果: {result}")
test_decorator_design_patterns()
1、单例模式(Singleton)
实现思路:通过装饰器缓存类实例,保证同一类只创建一个对象。
keys: 使用线程锁保证线程安全。重写__call__方法控制实例创建。效果:多次实例化返回同一对象,节省资源。
2、观察者模式(Observable)
实现思路:装饰函数,支持添加多个观察者,函数调用前后通知观察者。关键点:观察者实现before_call和after_call方法。装饰器维护观察者列表,调用时依次通知。应用场景:日志记录、性能监控、事件驱动等。
3、策略模式(Strategy)
实现思路:通过装饰器注册不同策略函数,统一管理并动态执行。关键点:使用字典存储策略名称与函数映射,通过execute方法调用指定策略。优势:策略扩展方便,调用灵活。
4、命令模式(Command)
实现思路:装饰函数,封装调用信息(参数、时间、结果),支持命令历史管理。关键点:记录每次调用的详细信息。提供撤销(undo)接口(简化示例)。应用场景:操作日志、事务管理、撤销功能。
5、装饰器模式(DecoratorPattern)
实现思路:通过递归装饰器包装组件,动态添加功能。关键点:基类DecoratorPattern持有组件引用。子类实现具体功能(如日志、计时)。优势:功能扩展灵活,符合开闭原则。
1009

被折叠的 条评论
为什么被折叠?



