Python 使包装器显示为它在help()中包装的函数

Python 使包装器显示为它在help()中包装的函数,python,wrapper,docstring,pydoc,Python,Wrapper,Docstring,Pydoc,不幸的是,我正在使用python2.4(不是出于选择),因此在2.5中添加的精彩内容(如functools)都不能帮助我 我想包装一个函数,但要使它在执行帮助(包装)时看起来就是它包装的函数 通过这样做,我已经部分实现了这一点 def a(): """a's docstring""" pass def wrapper(): a() wrapper.func_name = a.func_name #or should this use __name__ ? wrappe

不幸的是,我正在使用python2.4(不是出于选择),因此在2.5中添加的精彩内容(如functools)都不能帮助我

我想包装一个函数,但要使它在执行帮助(包装)时看起来就是它包装的函数

通过这样做,我已经部分实现了这一点

def a():
    """a's docstring"""
    pass

def wrapper():
    a() 
wrapper.func_name = a.func_name #or should this use __name__ ?
wrapper.func_doc = a.func_doc #or should this use __doc__ ?
现在执行
help(wrapper)
显示函数名的
a
,以及
a
的docstring。除了感觉不舒服外,这还不包括以下情况下的功能参数:

def b(x, y, z): 
    return a+b+c #or whatever

def wrapper(*args, **kwargs):
    #do something with the arguments
    return b(*args **kwargs)
help(wrapper)
会使其显示为
b(*args,**kwargs)
这显然不是我想要的。
dir(a)
中似乎没有任何属性可以帮助我,除非它嵌套在某个地方


编辑: 如果您可以使用pypi,请查看有助于此的装饰器模块。

使用

注意,它没有伪造参数规范。您可能可以这样做(使用
inspect.getargspec
来计算
foo
的参数规范,然后对
bar
进行黑客攻击),但这不是常规做法


编辑:由于您使用的是Python 2.4,因此必须重新实现
functools.wrapps
的功能。幸运的是,它实际上相当简单;它只需复制属性
\uuuu module\uuuuu
\uuu name\uuuu
\uuuu doc\uuuuuu
,然后用包装函数的
\uuu dict\uuuuuuu
更新包装器的
\uu dict>。所以你可以做:

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)

def update_wrapper(wrapper,
                   wrapped,
                   assigned = WRAPPER_ASSIGNMENTS,
                   updated = WRAPPER_UPDATES):
    for attr in assigned:
        setattr(wrapper, attr, getattr(wrapped, attr))
    for attr in updated:
        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    # Return the wrapper so this can be used as a decorator via partial()
    return wrapper

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)
(仅供参考,这是
functools.wrapps
的实际源代码)

使用

注意,它没有伪造参数规范。您可能可以这样做(使用
inspect.getargspec
来计算
foo
的参数规范,然后对
bar
进行黑客攻击),但这不是常规做法


编辑:由于您使用的是Python 2.4,因此必须重新实现
functools.wrapps
的功能。幸运的是,它实际上相当简单;它只需复制属性
\uuuu module\uuuuu
\uuu name\uuuu
\uuuu doc\uuuuuu
,然后用包装函数的
\uuu dict\uuuuuuu
更新包装器的
\uu dict>。所以你可以做:

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)

def update_wrapper(wrapper,
                   wrapped,
                   assigned = WRAPPER_ASSIGNMENTS,
                   updated = WRAPPER_UPDATES):
    for attr in assigned:
        setattr(wrapper, attr, getattr(wrapped, attr))
    for attr in updated:
        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    # Return the wrapper so this can be used as a decorator via partial()
    return wrapper

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)

(仅供参考,这是
functools.wrapps
的实际源代码)

如果我不必使用python2.4,这就可以了哈哈。我应该提到that@xhainingx您必须查看
包装的源代码,然后自己重新实现它。或者,更好的办法是升级到一个不过时的Python版本。如果由我决定的话,我很乐意这么做。旧式系统,如果您想自己实现,
functools
源代码位于。因此,使用
partial
的源代码将完成第一部分,但它看起来不包括参数。这仍然是我的主要问题。如果我不必使用python2.4,这将是好的哈哈。我应该提到that@xhainingx您必须查看
包装的源代码,然后自己重新实现它。或者,更好的办法是升级到一个不过时的Python版本。如果由我决定的话,我很乐意这么做。旧式系统,如果您想自己实现,
functools
源代码位于。因此,使用
partial
的源代码将完成第一部分,但它看起来不包括参数。这仍然是我的主要问题。是的,你应该使用
\uuu name\uuuuuu
\uuuu doc\uuuuuu
。顺便说一句,任何人都可以阅读。我想Decorator.Decorator可以解决这个问题,可惜我用的是python2.4-u-是的,你应该用
\uuuu name\uuu
\uuu doc\u
。顺便说一句,有人读过这个吗。我想Decorator.Decorator可以解决这个问题,可惜我用的是python2.4-_-