2

不幸的是,我正在使用 python 2.4(不是选择),所以 2.5 中添加的任何美妙的东西(例如 functools)都不能帮助我

我想包装一个函数,但是让它在你做 help(wrapper) 时看起来是它包装的函数

我通过做部分实现了这一点

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文档字符串。除了感觉 hacky 之外,这不包括以下情况下的函数参数:

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,请查看有助于解决此问题的装饰器模块。

4

1 回答 1

4

使用functools.wraps.

请注意,它不会伪造参数规范。您可能可以这样做(使用inspect.getargspec计算参数规范foo然后 hacking bar),但这不是传统的。


编辑:由于您使用的是 Python 2.4,因此您必须重新实现functools.wraps. 幸运的是,它实际上非常简单;它只是复制属性__module__,__name____doc__,然后__dict__用包装函数的__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.wraps。)

于 2012-12-28T19:54:28.313 回答