python装饰器进阶与设计模式

目录

装饰器

应用实例

装饰器的高级用法与内部机制

装饰器的执行时机与作用域

高级装饰器模式

装饰器性能优化

类装饰器与函数装饰器

装饰器在设计模式中的应用

1、单例模式(Singleton)

2、观察者模式(Observable)

3、策略模式(Strategy)

4、命令模式(Command)

5、装饰器模式(DecoratorPattern)


装饰器

装饰器是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持有组件引用。子类实现具体功能(如日志、计时)。优势:功能扩展灵活,符合开闭原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值