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

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

admin3周前 (03-23)Python23
# 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 教程] OpenCV 绘图教程:图形与文本标注

OpenCV 绘图教程:图形与文本标注本文介绍如何在 OpenCV 中绘制各种图形和添加文本,用于图像标注和可视化。一、绘制基本图形1.1 创建画布import cv2 import&nb...

[Python 教程] Matplotlib 数据可视化教程

Matplotlib 数据可视化教程 Matplotlib 是 Python 最常用的绘图库。本文介绍常用图表的绘制方法。 一、基础设置 import matplotlib.pyplot as pl...

Python 装饰器实用技巧:从入门到精通

装饰器是 Python 最强大的特性之一,但也是很多开发者感到困惑的概念。简单来说,装饰器是一个函数,它接受另一个函数作为输入,并返回一个新的函数。使用装饰器,你可以在不修改原函数代码的情况下,为其添...

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

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

Python 装饰器实战:从基础到高级应用的完整指南

装饰器是 Python 中最优雅也最强大的特性之一。它允许你在不修改原函数代码的前提下,动态地添加功能。本文将带你从装饰器的基础概念出发,逐步掌握其在实际开发中的高级应用技巧。许多初学者对装饰器感到困...

Python 装饰器:从入门到实战的完整指南

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

发表评论

访客

看不清,换一张

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