装饰器python库隐藏了args里面的kwargs

时间:2011-07-14 21:59:05

标签: python decorator kwargs

我使用装饰器库得到了一个非常奇怪的行为,这将在下一个代码中解释:

from decorator import decorator    

@decorator
def wrap(f, a, *args, **kwargs):
    print 'Decorator:', a, args, kwargs
    return f(a, *args, **kwargs)

def mywrap(f):
    def new_f(a, *args, **kwargs):
        print 'Home made decorator:', a, args, kwargs
        return f(a, *args, **kwargs)
    return new_f

@wrap
def funcion(a, b, *args, **kwargs):
    pass

@mywrap
def myfuncion(a, b, *args, **kwargs):
    pass

funcion(1, b=2)
myfuncion(1, b=2)

执行此脚本会打印:

$ python /tmp/test.py 
Decorator: 1 (2,) {}
Home made decorator: 1 () {'b': 2}

'decorator'隐藏了args中的kwargs,如何在不使用“自制”装饰器的情况下解决这个问题。

感谢。

1 个答案:

答案 0 :(得分:5)

仅仅因为你调用b=2的函数不会使b成为关键字参数; b是原始函数中的位置参数。如果没有名为b的参数并且您指定了b=2,那么 b将成为关键字参数。

decorator的行为实际上是最正确的;它生成的包装器与funcion()具有相同的签名,而由“自制”装饰器创建的包装器没有b作为命名参数。 “自制”包装器“错误地”将b放入kwargs,因为myfuncion()的签名(表明b不是关键字arg)隐藏在呼叫者。

保留功能签名是decorator中的一项功能,而不是错误。