Python装饰器的高级用法:如何巧妙运用functools模块实现优雅的函数包装与性能优化

Python装饰器的高级用法:如何巧妙运用functools模块实现优雅的函数包装与性能优化
最新回答
落寞式孤独

2026-10-27 12:42:31

Python装饰器的高级用法中,functools模块提供了多种工具来实现优雅的函数包装与性能优化。以下是具体技巧和示例:

1. 使用functools.wraps保留函数元信息

装饰器会修改被装饰函数的元信息(如__name__、__doc__),而functools.wraps可以保留这些信息。

from functools import wrapsdef better_log(func): @wraps(func) # 保留原函数的元信息 def wrapper(*args, kwargs): print(f"调用了函数: {func.__name__}") return func(*args, kwargs) return wrapper@better_logdef greet(name): """打个招呼""" return f"你好,{name}!"print(greet.__name__) # 输出: greetprint(greet.__doc__) # 输出: 打个招呼2. 带参数的装饰器

通过嵌套函数实现带参数的装饰器,灵活控制装饰行为。

from functools import wrapsimport timedef retry(max_tries=3, delay=1): def decorator(func): @wraps(func) def wrapper(*args, kwargs): tries = 0 while tries < max_tries: try: return func(*args, kwargs) except Exception as e: tries += 1 if tries == max_tries: raise e print(f"重试第{tries}次...") time.sleep(delay) return None return wrapper return decorator@retry(max_tries=2, delay=0.5)def flakey_function(): import random if random.random() < 0.7: raise ValueError("糟糕,出错了!") return "成功啦!"3. functools.lru_cache性能优化

通过缓存函数结果提升递归或重复调用的性能。

from functools import lru_cache@lru_cache(maxsize=128) # 缓存最近128次调用的结果def fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2)# 测试性能import timestart = time.time()print(fibonacci(100)) # 直接计算,无缓存时极慢print(f"用时: {time.time() - start}秒")

注意:maxsize=None表示无限缓存,但可能增加内存消耗。

4. 装饰器链式调用

多个装饰器可以叠加使用,执行顺序从内到外。

def bold(func): @wraps(func) def wrapper(): return f"<b>{func()}</b>" return wrapperdef italic(func): @wraps(func) def wrapper(): return f"<i>{func()}</i>" return wrapper@bold@italicdef hello(): return "Python装饰器真好玩"print(hello()) # 输出: <b><i>Python装饰器真好玩</i></b>5. 临时禁用装饰器

调试时可通过注释@快速禁用装饰器,无需修改装饰器代码。

# @better_log # 临时禁用def greet(name): return f"你好,{name}!"关键点总结
  • functools.wraps:保留被装饰函数的元信息,避免调试混乱。
  • 带参数装饰器:通过嵌套函数实现灵活配置(如重试次数、延迟)。
  • lru_cache:优化递归或重复计算,但需注意缓存大小。
  • 链式调用:按需组合多个装饰器,注意执行顺序。
  • 调试技巧:注释@快速禁用装饰器,简化调试过程。

合理使用这些技巧,可以显著提升代码的优雅性和性能,但需避免过度装饰导致逻辑复杂化。