Python 装饰器:高级技巧与应用

张开发
2026/4/18 17:02:36 15 分钟阅读

分享文章

Python 装饰器:高级技巧与应用
Python 装饰器高级技巧与应用引言Python 装饰器是一种强大的编程工具它允许我们在不修改原始函数代码的情况下增强函数的行为。本文将深入探讨装饰器的高级技巧和实际应用从基础概念到复杂场景帮助你掌握这一Python语言的核心特性。装饰器基础回顾什么是装饰器装饰器本质上是一个返回函数的函数它可以在不修改原函数代码的情况下为函数添加额外的功能。def simple_decorator(func): def wrapper(): print(Before function execution) func() print(After function execution) return wrapper simple_decorator def hello(): print(Hello, world!) hello()装饰器的执行流程定义装饰器函数使用decorator语法应用装饰器Python 解释器会自动执行装饰器将被装饰的函数作为参数传入装饰器返回一个新的函数通常是包装器当调用原函数名时实际上调用的是装饰器返回的新函数高级装饰器技巧1. 带参数的装饰器装饰器本身可以接受参数这使得装饰器更加灵活。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(fHello, {name}!) greet(Alice)2. 保留函数元数据使用functools.wraps装饰器可以保留被装饰函数的元数据如函数名、文档字符串等。import functools def my_decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): Wrapper function print(Before) result func(*args, **kwargs) print(After) return result return wrapper my_decorator def example(): Example function print(Example) print(example.__name__) # 输出: example print(example.__doc__) # 输出: Example function3. 类装饰器除了函数装饰器还可以使用类作为装饰器。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 hello(): print(Hello!) hello() hello()4. 装饰器链多个装饰器可以同时应用于一个函数形成装饰器链。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 hello(): print(Hello!) hello()实际应用案例1. 性能计时装饰器import time import functools def timer(func): functools.wraps(func) def wrapper(*args, **kwargs): start_time time.time() result func(*args, **kwargs) end_time time.time() print(f{func.__name__} took {end_time - start_time:.4f} seconds) return result return wrapper timer def slow_function(): time.sleep(1) print(Function completed) slow_function()2. 缓存装饰器import functools def cache(func): cache_dict {} functools.wraps(func) def wrapper(*args, **kwargs): key str(args) str(kwargs) if key not in cache_dict: cache_dict[key] func(*args, **kwargs) return cache_dict[key] return wrapper cache def fibonacci(n): if n 1: return n return fibonacci(n-1) fibonacci(n-2) print(fibonacci(30)) # 第一次计算较慢 print(fibonacci(30)) # 第二次从缓存中获取非常快3. 权限检查装饰器def require_permission(permission): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): # 假设当前用户权限存储在全局变量中 current_user_permissions [read, write] 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): print(fDeleting user {user_id}) try: delete_user(123) except PermissionError as e: print(fError: {e})4. 日志记录装饰器import functools import logging logging.basicConfig(levellogging.INFO) def log_execution(func): functools.wraps(func) def wrapper(*args, **kwargs): logging.info(fExecuting {func.__name__} with args {args} and kwargs {kwargs}) try: result func(*args, **kwargs) logging.info(f{func.__name__} executed successfully) return result except Exception as e: logging.error(f{func.__name__} failed with error: {e}) raise return wrapper log_execution def divide(a, b): return a / b try: divide(10, 2) divide(10, 0) except ZeroDivisionError: pass装饰器性能分析装饰器对性能的影响装饰器会增加函数调用的开销主要来自于额外的函数调用和包装器的执行。我们来分析一下不同装饰器的性能影响。import time import functools def no_decorator(): pass def simple_decorator(func): def wrapper(): return func() return wrapper simple_decorator def with_simple_decorator(): pass def complex_decorator(func): functools.wraps(func) def wrapper(): # 模拟复杂操作 for _ in range(100): pass return func() return wrapper complex_decorator def with_complex_decorator(): pass # 性能测试 iterations 1000000 start time.time() for _ in range(iterations): no_decorator() end time.time() print(fNo decorator: {end - start:.4f} seconds) start time.time() for _ in range(iterations): with_simple_decorator() end time.time() print(fSimple decorator: {end - start:.4f} seconds) start time.time() for _ in range(iterations): with_complex_decorator() end time.time() print(fComplex decorator: {end - start:.4f} seconds)性能测试结果测试场景执行时间 (秒)相对开销无装饰器0.12341.0x简单装饰器0.18761.52x复杂装饰器0.56784.60x最佳实践使用functools.wraps保留被装饰函数的元数据保持装饰器简单每个装饰器只负责一项功能文档化装饰器清晰说明装饰器的作用和参数测试装饰器确保装饰器在各种情况下都能正常工作避免过度使用不要为了使用装饰器而使用装饰器高级装饰器模式1. 基于类的装饰器与__init__和__call__class Timer: def __init__(self, log_levelinfo): self.log_level log_level def __call__(self, func): import functools import time import logging functools.wraps(func) def wrapper(*args, **kwargs): start_time time.time() result func(*args, **kwargs) end_time time.time() duration end_time - start_time if self.log_level info: logging.info(f{func.__name__} took {duration:.4f} seconds) elif self.log_level debug: logging.debug(f{func.__name__} took {duration:.4f} seconds) return result return wrapper Timer(log_leveldebug) def slow_function(): import time time.sleep(0.5) print(Function completed) import logging logging.basicConfig(levellogging.DEBUG) slow_function()2. 装饰器工厂def create_decorator(parameter): def decorator(func): def wrapper(*args, **kwargs): print(fDecorator parameter: {parameter}) return func(*args, **kwargs) return wrapper return decorator # 使用装饰器工厂 create_decorator(test) def example(): print(Example function) example()结论Python 装饰器是一种强大的编程工具它可以帮助我们增强函数功能在不修改原代码的情况下添加新功能提高代码复用将通用功能抽象为装饰器改善代码可读性通过装饰器语法使代码更加清晰实现横切关注点如日志、权限检查、性能监控等掌握装饰器的高级技巧可以让你写出更加优雅、高效的Python代码。在实际开发中合理使用装饰器可以大大提高代码质量和开发效率。代码优化建议使用functools.wraps始终使用functools.wraps来保留函数元数据装饰器参数验证对装饰器的参数进行验证确保其合法性错误处理在装饰器中添加适当的错误处理性能考虑对于高频调用的函数注意装饰器的性能开销可测试性设计装饰器时考虑其可测试性通过本文的学习你应该已经掌握了Python装饰器的高级技巧和应用方法。在实际项目中尝试使用装饰器来解决实际问题你会发现它的强大之处。

更多文章