将调用签名复制到装饰器

11 投票
3 回答
1470 浏览
提问于 2025-04-15 23:36

如果我这样做:

def mydecorator(f):
    def wrapper(*args, **kwargs):
        f(*args, **kwargs)
    wrapper.__doc__ = f.__doc__
    wrapper.__name__ = f.__name__
    return wrapper

@mydecorator
def myfunction(a,b,c):
    '''My docstring'''
    pass

然后我输入 help myfunction,我得到:

Help on function myfunction in module __main__:

myfunction(*args, **kwargs)
    My docstring

所以函数的名字和文档说明都正确地复制过来了。有没有办法也把实际的调用签名,比如 (a, b, c),一起复制过来呢?

3 个回答

1

这个功能是由Python标准库中的inspect模块提供的,具体是通过inspect.getargspec来实现的。

>>> import inspect
>>> def f(a, b, c=0, *args, **kwargs): return
... 
>>> inspect.getargspec(f)
ArgSpec(args=['a', 'b', 'c'], varargs='args', keywords='kwargs', defaults=(0,))
3

你可以试试这个叫做 decorator 的模块,链接在这里: http://pypi.python.org/pypi/decorator/3.2.0

相关的文档部分在这里: http://micheles.googlecode.com/hg/decorator/documentation.html#statement-of-the-problem

9

这里有一个例子,使用了Michele Simionato的decorator模块来修正函数的签名:

import decorator

@decorator.decorator
def mydecorator(f,*args, **kwargs):
    return f(*args, **kwargs)

@mydecorator
def myfunction(a,b,c):
    '''My docstring'''
    pass

help(myfunction)
# Help on function myfunction in module __main__:

# myfunction(a, b, c)
#     My docstring

撰写回答