Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理docstring的Python装饰器_Python_Decorator_Docstring - Fatal编程技术网

处理docstring的Python装饰器

处理docstring的Python装饰器,python,decorator,docstring,Python,Decorator,Docstring,我在装饰程序中使用docstring时遇到问题。给出以下示例: def decorator(f): def _decorator(): print 'decorator active' f() return _decorator @decorator def foo(): '''the magic foo function''' print 'this is function foo' help(foo) 现在,帮助没有按预期

我在装饰程序中使用docstring时遇到问题。给出以下示例:

def decorator(f):
    def _decorator():
        print 'decorator active'
        f()
    return _decorator

@decorator
def foo():
    '''the magic foo function'''
    print 'this is function foo'

help(foo)
现在,帮助没有按预期显示
foo
的docstring,它显示:

Help on function _decorator in module __main__:

_decorator()
如果没有decorator,则帮助是正确的:

Help on function foo in module __main__:

foo()
    the magic foo function

我知道,函数
foo
是由decorator包装的,因此函数对象不再是函数
foo
。但是,要获得预期的文档字符串(以及帮助),什么是好的解决方案呢?

我找到了一个解决方案,但不知道它是否真的好:

def decorator(f):
    def _decorator():
        print 'decorator active'
        f()
    _decorator.__name__=f.__name__
    _decorator.__doc__=f.__doc__
    return _decorator
带有
\u decorator.\uuuuuuu name\uuuuuu=f.\uuuuu name\uuuuuuu
的部分看起来有点可怕。。。您认为如何?

使用
functools.wrapps()
更新装饰器的属性:

from functools import wraps

def decorator(f):
    @wraps(f)
    def _decorator():
        print 'decorator active'
        f()
    return _decorator

@decorator
def foo():
    '''the magic foo function'''
    print 'this is function foo'

help(foo)

另请参见for
functools

查看
functools.wrapps

如果
foo
接受任何参数,则这不起作用-它们将被
\u decorator
使用的任何参数替换。这是一个问题,尤其是当您希望您的装饰者使用
*args、**kwds
时。我一直无法找到使用
functools.wrapps
@Scott Griffiths获得正确文档字符串的方法:即使
foo
使用参数,文档字符串仍然是正确的。但是,
help(foo)
将显示
\u decorator
的参数列表,因为它实际上替换了
foo
函数。如果您正在编写使用
*args、**kwargs
接受任意参数的修饰符,那么没有好办法解决这个问题,但对我来说,重要的一点是docstring保持完整。为了清晰起见,可以在docstring中指定参数详细信息。感谢提供额外信息。最近,我一直未能获得装饰函数的正确帮助描述-这似乎是一个相当糟糕的状态,但我理解困难,因为装饰函数可能具有完全不同的签名。不过,一定有办法……:)有一种方法可以做到这一点。decorator模块通过使用技巧来实现这一点。诀窍是重新生成decorator签名并在其上运行exec。您可以在decorator.py的第118行中找到诀窍。然而,我认为这种方法是极端的。看来functools.wrapps现在确实可以使
help()
正常工作。我很难找到这是什么时候改变的,但我仍然在使用Python2.7。快乐的一天!事实上,这(几乎?)正是functools.wrapps所做的:)在我看来并不可怕。它说的正是你想要它说的。“我希望这个函数的名称是‘myfunction’,而不是‘装饰者’。”你不应该重新发明轮子,特别是当标准库中有一个工作函数可以实现这一点时,经过良好测试、维护和记录。我不能与@Azat Ibrakov一起使用;我总是喜欢一个清晰易读的解决方案,它不依赖于任何库(最终也会改变)。因此,我真的很喜欢这种简单直接的方法(+1)。此外,此解决方案不会复制
f
(如果有)和返回类型的参数的docstring<代码>functools.wrapps可执行此操作。