我正在尝试确保help()在Python 2.7上运行REPL显示包含__doc__的函数functools.partial.目前运行help()在一个functools.partial"功能"显示__doc__的的functools.partial类,而不是我的包裹功能的__doc__.有没有办法实现这个目标?
考虑以下callables:
def foo(a):
"""My function"""
pass
partial_foo = functools.partial(foo, 2)
Run Code Online (Sandbox Code Playgroud)
跑步help(foo)将导致显示foo.__doc__.但是,运行help(partial_foo)结果__doc__是Partial对象.
我的第一个方法是使用functools.update_wrapper其正确替换部分对象的__doc__用foo.__doc__.但是,由于pydoc的原因,这并不能解决"问题" .
我已经调查了pydoc代码,问题似乎partial_foo是实际上是一个Partial对象而不是典型的函数/可调用,有关该细节的更多信息,请参阅此问题.
默认情况下,pydoc将显示__doc__对象类型,而不是实例,如果传递的对象被inspect.isclass确定为类.有关代码本身的更多信息,请参阅render_doc函数.
所以,在上面的场景中,pydoc显示了类型的帮助,而functools.partial不是__doc__我的functools.partial实例.
反正有没有改变我的调用help()或functools.partial传递的实例,help()以便它将显示__doc__实例,而不是类型?
我找到了一个非常古怪的方法来做到这一点。我编写了以下函数来覆盖该__builtins__.help函数:
def partialhelper(object=None):
if isinstance(object, functools.partial):
return pydoc.help(object.func)
else:
# Preserve the ability to go into interactive help if user calls
# help() with no arguments.
if object is None:
return pydoc.help()
else:
return pydoc.help(object)
Run Code Online (Sandbox Code Playgroud)
然后只需在 REPL 中将其替换为:
__builtins__.help = partialhelper
Run Code Online (Sandbox Code Playgroud)
这很有效,而且似乎还没有任何重大缺点。但是,上述简单的实现没有办法支持仍然显示__doc__某些对象 functools.partial。它要么全有,要么全无,但可能会向包装的(原始)函数附加一个属性,以指示原始函数是否__doc__应显示原始函数。然而,在我的场景中,我永远不想这样做。
请注意,使用 IPython 和嵌入功能时,上述内容不起作用。这是因为 IPython 直接通过引用 'real' 来设置 shell 的命名空间__builtin__,请参阅代码和旧邮件列表以获取有关原因的信息。
因此,经过一番调查后,还有另一种方法可以将其侵入 IPython。我们必须重写该类site._Helper,IPython 使用该类来显式设置帮助系统。以下代码将在调用 BEFORE 时执行此操作IPython.embed:
import site
site._Helper.__call__ = lambda self, *args, **kwargs: partialhelper(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
我在这里还缺少其他缺点吗?
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |