当前位置:首页 > Python > 正文内容

Python 装饰器进阶:从基础到实战

admin2周前 (03-23)Python20
# Python 装饰器进阶:从基础到实战 装饰器是 Python 中最优雅的特性之一,它允许我们在不修改函数代码的情况下扩展其功能。本文将深入探讨装饰器的高级用法,并通过实际案例展示其强大之处。 ## 装饰器基础回顾 装饰器本质上是一个接收函数作为参数并返回新函数的高阶函数。最简单的装饰器形式如下: ```python def simple_decorator(func): def wrapper(*args, **kwargs): print(f"调用函数: {func.__name__}") result = func(*args, **kwargs) print(f"函数执行完毕") return result return wrapper @simple_decorator def greet(name): return f"你好, {name}!" print(greet("小明")) ``` ## 带参数的装饰器 有时候我们需要装饰器接受自定义参数。这需要使用三层嵌套结构:参数层、装饰器层、包装层。 ```python def repeat(times=2): """重复执行装饰器""" def decorator(func): def wrapper(*args, **kwargs): results = [] for _ in range(times): result = func(*args, **kwargs) results.append(result) return results[-1] # 返回最后一次的结果 return wrapper return decorator @repeat(times=3) def process_data(data): print(f"处理数据: {data}") return len(data) result = process_data("hello") print(f"最终结果: {result}") ``` ## 类装饰器 类也可以作为装饰器,这使得我们可以更好地维护装饰器的状态。 ```python class TimerDecorator: """计时器类装饰器""" def __init__(self, precision=2): self.precision = precision def __call__(self, func): import time def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() elapsed = round(end - start, self.precision) print(f"{func.__name__} 执行时间: {elapsed}秒") return result return wrapper @TimerDecorator(precision=4) def slow_operation(): import time time.sleep(0.1) return "完成" slow_operation() ``` ## 保留函数元数据 使用装饰器时,原始函数的元信息(如 __name__、__doc__)会被覆盖。Python 提供了 functools.wraps 来解决这个问题。 ```python import functools def log_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f"[LOG] 调用 {func.__name__}") return func(*args, **kwargs) return wrapper @log_decorator def calculate(x, y): """计算两个数的和""" return x y print(calculate.__name__) # 输出: calculate print(calculate.__doc__) # 输出: 计算两个数的和 ``` ## 实战应用:缓存装饰器 缓存装饰器可以显著提高重复调用函数的性能,特别是对于计算密集型操作。 ```python import functools class Memoize: """带超时的缓存装饰器""" def __init__(self, ttl=60): self.ttl = ttl # 缓存有效期(秒) self.cache = {} def __call__(self, func): @functools.wraps(func) def wrapper(*args, **kwargs): import time # 创建缓存键 key = (args, frozenset(kwargs.items())) if key in self.cache: value, timestamp = self.cache[key] if time.time() - timestamp < self.ttl: print(f"[缓存命中] {func.__name__}{args}") return value # 计算新值 result = func(*args, **kwargs) self.cache[key] = (result, time.time()) return result return wrapper @Memoize(ttl=10) def expensive_computation(n): """模拟耗时计算""" import time print(f"执行复杂计算: {n}") time.sleep(0.5) # 模拟耗时操作 return n ** 2 print(expensive_computation(5)) # 执行计算 print(expensive_computation(5)) # 从缓存读取 ``` ## 实战应用:权限验证装饰器 在 Web 开发中,权限验证是常见需求,装饰器可以优雅地实现这一功能。 ```python class AuthDecorator: """权限验证装饰器""" def __init__(self, required_role): self.required_role = required_role def __call__(self, func): @functools.wraps(func) def wrapper(*args, **kwargs): # 模拟从上下文获取用户信息 user = kwargs.get('user', {'role': 'guest'}) if user['role'] != self.required_role: raise PermissionError( f"权限不足: 需要 {self.required_role}," f"当前是 {user['role']}" ) return func(*args, **kwargs) return wrapper @AuthDecorator(required_role='admin') def delete_resource(resource_id, user): """删除资源(需要管理员权限)""" print(f"删除资源: {resource_id}") return True # 测试权限验证 try: delete_resource(123, user={'role': 'admin'}) # 成功 delete_resource(123, user={'role': 'user'}) # 失败 except PermissionError as e: print(f"错误: {e}") ``` ## 装饰器链 多个装饰器可以叠加使用,执行顺序是从下往上(从内向外)。 ```python def bold(func): @functools.wraps(func) def wrapper(*args, **kwargs): return f"{func(*args, **kwargs)}" return wrapper def italic(func): @functools.wraps(func) def wrapper(*args, **kwargs): return f"{func(*args, **kwargs)}" return wrapper @bold @italic def format_text(text): return text print(format_text("重要提示")) # 输出: 重要提示 ``` ## 最佳实践 1. **总是使用 functools.wraps**:保留被装饰函数的元数据 2. **保持装饰器简单**:复杂的逻辑应该分解成多个装饰器 3. **文档化装饰器**:清晰的文档字符串说明装饰器的用途 4. **考虑类装饰器**:需要维护状态时,类装饰器更合适 5. **谨慎处理异常**:装饰器不应该意外吞掉异常 ## 总结 Python 装饰器是 AOP(面向切面编程)思想的优雅实现。通过装饰器,我们可以: - 分离关注点(日志、计时、验证等) - 提高代码复用性 - 保持核心逻辑的简洁 掌握装饰器的高级用法,将让你的 Python 代码更加优雅和高效。

相关文章

Python 装饰器的 5 个实用技巧,让你的代码更优雅

在 Python 编程中,装饰器(Decorator)是一个强大而优雅的工具。很多初学者对装饰器的理解停留在@staticmethod 或@classmethod 这类内置装饰器上,但实际上,自定义装...

Python 装饰器的实用技巧与高级用法

装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数。理解这一点是掌握装饰器的关键。让我们从最简单的例子开始,逐步深入到复杂的应用场景。首先,我们需要理解函数在 Python 中是一等公民。这意味...

Python 生成器进阶:理解 yield 与构建高效迭代器

在 Python 开发中,我们经常需要处理大量数据或流式数据,如果一次性将所有数据加载到内存中,不仅会占用大量内存空间,还可能导致程序运行缓慢甚至崩溃。生成器(Generator)正是解决这个问题的利...

深入理解 Python 装饰器:从基础到高级的完整指南

什么是装饰器?装饰器本质上是一个 Python 函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能。装饰器的返回值通常也是一个函数对象。这种设计模式遵循了"开放封闭原则"——对扩展开放,...

Python 上下文管理器实战指南:优雅处理资源的艺术

# Python 上下文管理器实战指南:优雅处理资源的艺术 在 Python 编程中,资源的获取与释放是一个永恒的主题。文件操作、数据库连接、网络请求、锁的获取...这些场景都遵循相同的模式:打开资...

Python 装饰器高级实战:从基础到精通的5个实用技巧

引言:为什么要深入掌握装饰器? 装饰器是 Python 中最优雅的元编程工具之一,它能在不修改原函数代码的情况下,动态地增加功能。很多开发者都知道如何使用 @timer 计时或 @cache 缓存,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。