Python 高级技巧:保持装饰器不改变函数元信息
作者:野牛程序员:2025-12-22 11:29:32python阅读 2025
Python 高级技巧:保持装饰器不改变函数元信息
# /*
# Python 高级技巧:保持装饰器不改变函数元信息
# --------------------------------------------------------
# 问题:
# 装饰器会返回一个新函数对象,导致原函数的 __name__、__doc__ 等元信息丢失。
#
# 解决方案:
# 使用 functools.wraps 修饰内部包装函数,保持原函数元信息。
# */
from functools import wraps
# ========================================
# 示例:不使用 wraps
def decorator_no_wraps(func):
def wrapper(*args, **kwargs):
"""包装函数"""
print("执行装饰器逻辑")
return func(*args, **kwargs)
return wrapper
@decorator_no_wraps
def greet(name):
"""打招呼函数"""
return f"Hello, {name}!"
print("不使用 wraps:")
print("函数名:", greet.__name__) # 输出 wrapper
print("文档:", greet.__doc__) # 输出 包装函数
print("-" * 40)
# ========================================
# 示例:使用 wraps
def decorator_with_wraps(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("执行装饰器逻辑")
return func(*args, **kwargs)
return wrapper
@decorator_with_wraps
def greet2(name):
"""打招呼函数"""
return f"Hello, {name}!"
print("使用 wraps:")
print("函数名:", greet2.__name__) # 输出 greet2
print("文档:", greet2.__doc__) # 输出 打招呼函数
# --------------------------------------------------------
# 要点总结:
# 1) functools.wraps 是 functools.update_wrapper 的装饰器形式;
# 2) 它会将原函数的 __name__、__doc__、__module__、__annotations__ 等元信息复制到包装函数;
# 3) 保证装饰后的函数依旧保留原函数特性;
# 4) 强烈建议在自定义装饰器时使用 wraps。
# */
#
# 不使用 wraps:
# 函数名: wrapper
# 文档: 包装函数
# ----------------------------------------
# 使用 wraps:
# 函数名: greet2
# 文档: 打招呼函数野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892

