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

IPython中被装饰器包装的函数无法显示文档字符串如何解决?

如何让被装饰的函数在IPython中正常显示自身文档字符串?

在IPython中运行以下代码后,执行func_with_wrap?会显示<no docstring>,但func_no_wrap?可以正常展示对应的文档字符串:

def wrap(f):
    """
    wrap docstring
    """
    def wrapped():
        return
    return wrapped

@wrap
def func_with_wrap():
    """
    func_with_wrap docstring
    """
    return

def func_no_wrap():
    """
    func_no_wrap docstring
    """
    return

IPython执行输出如下:

In [12]: func_with_wrap?
Signature: func_with_wrap()
Docstring: <no docstring>
File:      c:\confidential>
Type:      function

In [13]: func_no_wrap?
Signature: func_no_wrap()
Docstring: func_no_wrap docstring
File:      c:\confidential>
Type:      function

之后尝试了两种修改装饰器的方式:

  • 无效写法:
def wrap(f):
    """
    wrap docstring
    """
    def wrapped():
        wrapped.__doc__ = f.__doc__
        return
    return wrapped

这种写法下,IPython依然无法显示func_with_wrap的文档字符串。

  • 有效写法:
def wrap(f):
    """
    wrap docstring
    """
    def wrapped():
        return
    wrapped.__doc__ = f.__doc__
    return wrapped

问题解析与解决方案

问题核心在于:IPython执行?查看文档时,是直接读取函数对象的__doc__属性,不会触发函数调用。

第一种无效写法里,wrapped.__doc__ = f.__doc__写在wrapped函数内部,只有当func_with_wrap(即wrapped)被调用时才会执行赋值,IPython查看文档时不会调用函数,因此读取到的还是wrapped初始的空文档字符串。

而有效写法是在定义完wrapped后、返回它之前,直接将wrapped.__doc__赋值为原函数f的__doc__。装饰器完成对func_with_wrap的替换后,func_with_wrap的__doc__属性已经被正确设置,IPython就能直接读取到原函数的文档字符串。

另外,用Python标准库的functools.wraps装饰器可以更优雅地解决问题,它会自动把原函数的文档字符串、函数名等元信息复制到包装函数上:

import functools

def wrap(f):
    """
    wrap docstring
    """
    @functools.wraps(f)
    def wrapped():
        return
    return wrapped

@wrap
def func_with_wrap():
    """
    func_with_wrap docstring
    """
    return

这种写法不仅能保留文档字符串,还能保留原函数的名称、签名等信息,是更规范的装饰器实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:52:55