You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

装饰器隐藏类方法文档:如何恢复help()中的方法描述?

这个问题我太熟悉了!当你用装饰器修饰类方法后,调用help(class_name)看不到原方法的文档字符串,本质是因为装饰器默认会用一个新的函数(也就是装饰器里的wrapper)替换原方法,但这个新函数并没有继承原方法的元数据——包括文档字符串__doc__、函数名__name__这些关键信息,所以help()只能识别到装饰器内层函数的内容,而非你写的原方法文档。

最推荐的解决方案:用functools.wraps

Python标准库的functools.wraps就是专门解决这个痛点的——它会自动把原函数的所有元数据复制到装饰器返回的新函数上,让help()和其他依赖元数据的工具能正常识别原方法的信息。

先看错误示例(未处理的情况)

def my_decorator(func):
    def wrapper(*args, **kwargs):
        """这是装饰器内部的wrapper函数"""
        print("执行装饰器前置逻辑")
        return func(*args, **kwargs)
    return wrapper

class MyClass:
    @my_decorator
    def calculate(self, x, y):
        """计算两个数的和
        参数:
            x (int): 第一个数字
            y (int): 第二个数字
        返回:
            int: 两数之和
        """
        return x + y

help(MyClass.calculate)

运行这段代码,你会发现输出的是wrapper函数的文档,完全看不到原calculate方法的说明。


用functools.wraps修复后的代码

只需要给装饰器里的wrapper加上@functools.wraps(func)即可:

import functools

def my_decorator(func):
    # 关键一步:用wraps把原函数的元数据复制给wrapper
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        """这是装饰器内部的wrapper函数"""
        print("执行装饰器前置逻辑")
        return func(*args, **kwargs)
    return wrapper

class MyClass:
    @my_decorator
    def calculate(self, x, y):
        """计算两个数的和
        参数:
            x (int): 第一个数字
            y (int): 第二个数字
        返回:
            int: 两数之和
        """
        return x + y

help(MyClass.calculate)

现在再运行help(MyClass)或者help(MyClass.calculate),就能看到原方法完整的文档字符串了!

备选方案:手动用update_wrapper复制元数据

如果因为某些场景不能用wraps语法糖,也可以手动调用functools.update_wrapper来实现同样的效果,本质上wraps就是update_wrapper的简化封装:

import functools

def my_decorator(func):
    def wrapper(*args, **kwargs):
        """这是装饰器内部的wrapper函数"""
        print("执行装饰器前置逻辑")
        return func(*args, **kwargs)
    # 手动复制原函数元数据到wrapper
    functools.update_wrapper(wrapper, func)
    return wrapper

类形式装饰器的处理

如果你用的是类风格的装饰器,同样需要处理元数据传递,只需要在装饰器类的__init__方法里调用update_wrapper,把原函数的元数据复制到装饰器实例上:

import functools

class MyDecorator:
    def __init__(self, func):
        self.func = func
        # 复制原函数元数据到装饰器实例
        functools.update_wrapper(self, func)
    
    def __call__(self, *args, **kwargs):
        print("执行类装饰器逻辑")
        return self.func(*args, **kwargs)

class MyClass:
    @MyDecorator
    def calculate(self, x, y):
        """计算两个数的和"""
        return x + y

help(MyClass.calculate)
总结

不管是函数装饰器还是类装饰器,核心都是让装饰器返回的对象(函数或类实例)继承原方法的元数据。functools.wraps是最简洁、最推荐的方式,几乎所有自定义装饰器都应该加上它,避免出现元数据丢失的问题。

内容的提问来源于stack exchange,提问作者velvel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:52:19