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

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

admin7个月前 (03-23)Python224
# 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 装饰器的高级应用与实战技巧

装饰器本质上是接受函数作为参数并返回新函数的高阶函数。理解这一点是掌握装饰器的关键。让我们从基础开始,逐步深入到高级应用。首先,我们需要理解函数在 Python 中是一等公民。这意味着函数可以像其他对...

Python 装饰器完全指南:从原理到实战的 5 个核心场景

装饰器(Decorator)是 Python 中最具魅力的特性之一。它允许我们在不修改原函数代码的前提下,动态地添加功能。但很多开发者对装饰器的理解仅停留在在函数上面加个@符号的层面。今天,我们将从底...

Python 装饰器从入门到实战:5 个实用场景详解

装饰器(Decorator)是 Python 中一种优雅的设计模式,它允许我们在不修改原函数代码的前提下,动态地给函数添加功能。想象一下,你有一个已经写好的函数,现在想给它添加日志记录、性能监控或权限...

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

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

Python 异步编程实战指南:从入门到精通

Python 异步编程实战指南:从入门到精通 简介 在现代 Python 开发中,异步编程已经成为构建高性能应用程序的核心技能。特别是在处理 I/O 密集型任务(如网络请求...

Python装饰器完全指南:从原理到实践

Python装饰器是Python中最优雅的特性之一,它允许我们在不修改函数源代码的情况下,动态地扩展函数的功能。本文将从基础概念出发,深入讲解装饰器的原理、用法和最佳实践,帮助你真正掌握这一强大的Py...

发表评论

访客

看不清,换一张

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