跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Python 如何让一个函数在被装饰多次后还能正确显示帮助信息

Python函数多次装饰后帮助信息丢失,是因为装饰器用新函数替换原函数导致元数据被覆盖;解决方法是每层装饰器内部包装函数均使用@functools.wraps(func)自动复制__name__、__doc__等属性。 Python 中函数被多次装饰后帮助信息丢失,是因为装饰器通常会用新函数替换原函数,导致
help()
、
docstring
、函数名等元数据被覆盖。解决方法是让装饰器**保留原始函数的元数据**,核心是使用
functools.wraps
。 用
@functools.wraps
保留元数据 这是最标准、最推荐的做法。每次写装饰器时,在内层包装函数上加上
@wraps(func)
,它会自动复制
__name__
、
__doc__
、
__module__
、
__annotations__
等关键属性。 示例:
from functools import wraps

def log_calls(func): @wraps(func) # ← 关键:保留原函数元数据 def wrapper(*args, *kwargs): print(f"Calling {func.name}") return func(args, **kwargs) return wrapper

def add_one(func): @wraps(func) def wrapper(*args, *kwargs): result = func(args, **kwargs) return result + 1 return wrapper

@log_calls @add_one def square(x): """Return the square of x.""" return x * x

此时
help(square)
正确显示:
Help on function square in module __main__:
square(x)
Return the square of x.
立即学习 “ Python免费学习笔记(深入) ”; Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 多层装饰时,每层都要用
@wraps
如果装饰器嵌套三层(比如
@A
→
@B
→
@C
→ 函数),那么 A、B、C 三个装饰器内部的包装函数都必须各自调用
@wraps
。漏掉任意一层,元数据就会在那一层中断。 装饰器本身不加
@wraps
→ 元 数据丢失 只在最外层加,中间层没加 → 中间层已覆盖,外层补救无效 每一层都加 → 原始函数的
__doc__
和名字能穿透所有层级 检查是否生效的小技巧 调试时可快速验证:
print(square.__name__)
→ 应输出
'square'
,不是
'wrapper'
print(square.__doc__)
→ 应输出
"Return the square of x."
help(square)
→ 显示内容应和原始函数一致 不推荐的手动复制(仅作了解) 理论上可以手动赋值:
def bad_decorator(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) wrapper.__name__ = func.__name__ wrapper.__doc__ = func.__doc__ wrapper.__module__ = func.__module__ return wrapper
但容易遗漏属性(如
__annotations__
、
__dict__
),且不可靠。 务必优先使用
@functools.wraps
。

相关文章