Python 装饰器高级应用指南

张开发
2026/4/16 3:48:38 15 分钟阅读

分享文章

Python 装饰器高级应用指南
Python 装饰器高级应用指南1. 什么是装饰器装饰器是 Python 中一种特殊的语法结构用于修改函数或类的行为。它允许我们在不修改原函数代码的情况下为函数添加额外的功能。2. 基本语法装饰器使用符号来应用放在函数定义的上方。decorator def function(): pass3. 装饰器的实现3.1 简单装饰器def my_decorator(func): def wrapper(): print(Before function call) func() print(After function call) return wrapper my_decorator def say_hello(): print(Hello) say_hello() # 输出: # Before function call # Hello # After function call3.2 带参数的装饰器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 say_hello(name): print(fHello, {name}!) say_hello(Alice) # 输出: # Hello, Alice! # Hello, Alice! # Hello, Alice!3.3 保留函数元数据使用functools.wraps可以保留原函数的元数据如函数名、文档字符串等。import functools def my_decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): Wrapper function print(Before function call) result func(*args, **kwargs) print(After function call) return result return wrapper my_decorator def say_hello(): Say hello function print(Hello) print(say_hello.__name__) # 输出: say_hello print(say_hello.__doc__) # 输出: Say hello function4. 高级应用4.1 类装饰器类装饰器是使用类来实现的装饰器它通过__call__方法来实现装饰功能。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 # Hello4.2 装饰器链多个装饰器可以同时应用到一个函数上形成装饰器链。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 say_hello(): print(Hello) say_hello() # 输出: # Decorator 1 before # Decorator 2 before # Hello # Decorator 2 after # Decorator 1 after4.3 带状态的装饰器装饰器可以保持状态例如缓存函数结果。import functools def cache(func): Cache function results 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)) # 直接从缓存获取结果4.4 装饰器工厂装饰器工厂是返回装饰器的函数允许我们为装饰器提供配置参数。def log_level(level): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): print(f[{level.upper()}] Calling {func.__name__}) result func(*args, **kwargs) print(f[{level.upper()}] {func.__name__} completed) return result return wrapper return decorator log_level(info) def process_data(data): print(fProcessing data: {data}) return data * 2 log_level(error) def handle_error(): print(Handling error) process_data(42) # 输出: [INFO] Calling process_data # Processing data: 42 # [INFO] process_data completed handle_error() # 输出: [ERROR] Calling handle_error # Handling error # [ERROR] handle_error completed5. 实际应用场景5.1 日志记录def log_function(func): functools.wraps(func) def wrapper(*args, **kwargs): print(fCalling {func.__name__} with args: {args}, kwargs: {kwargs}) result func(*args, **kwargs) print(f{func.__name__} returned: {result}) return result return wrapper log_function def add(a, b): return a b add(3, 5) # 输出调用信息和返回值5.2 性能计时import time 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) return Done slow_function() # 输出执行时间5.3 权限验证def require_permission(permission): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): # 假设当前用户权限存储在 current_user.permissions 中 current_user {permissions: [read, write]} if permission not in current_user[permissions]: raise PermissionError(fRequired permission: {permission}) return func(*args, **kwargs) return wrapper return decorator require_permission(write) def create_post(content): print(fCreating post: {content}) return Post created require_permission(admin) def delete_post(post_id): print(fDeleting post: {post_id}) return Post deleted create_post(Hello World) # 成功执行 try: delete_post(1) except PermissionError as e: print(e) # 抛出权限错误5.4 输入验证def validate_input(*types): def decorator(func): functools.wraps(func) def wrapper(*args, **kwargs): for arg, type_ in zip(args, types): if not isinstance(arg, type_): raise TypeError(fExpected {type_}, got {type(arg)}) return func(*args, **kwargs) return wrapper return decorator validate_input(int, str) def process_user(user_id, name): print(fProcessing user {user_id}: {name}) return fUser {user_id} processed process_user(1, Alice) # 成功执行 try: process_user(1, Alice) except TypeError as e: print(e) # 抛出类型错误6. 最佳实践使用 functools.wraps保留原函数的元数据。保持装饰器简单每个装饰器只负责一项功能。使用装饰器工厂当需要为装饰器提供参数时。文档化装饰器为装饰器添加清晰的文档字符串。测试装饰器确保装饰器在各种情况下都能正常工作。7. 总结装饰器是 Python 中非常强大的功能它允许我们以一种简洁、优雅的方式修改函数或类的行为。通过掌握装饰器的高级应用我们可以编写更加模块化、可维护的代码。在实际应用中装饰器可以用于日志记录、性能计时、权限验证、输入验证等多种场景大大提高了代码的可读性和可维护性。希望本文对你理解和应用 Python 装饰器有所帮助

更多文章