2

我在装饰器库中遇到了一个非常奇怪的行为,下面的代码将对此进行解释:

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' 将 kwargs 隐藏在 args 中,我如何在不使用“自制”装饰器的情况下解决这个问题。

谢谢。

4

1 回答 1

5

仅仅因为您调用函数 withb=2不会产生b关键字参数;b是原始函数中的位置参数。如果没有命名的参数b并且您指定了b=2则 then b将成为关键字参数。

decorator的行为其实是最正确的;它生成的包装器具有与 相同的签名funcion(),而您的“自制”装饰器制作的包装器没有b作为命名参数。“自制”包装器“错误地”放入bkwargs因为对调用者隐藏了 的签名myfuncion(),这清楚地表明b它不是关键字 arg。

保留函数签名是decorator.

于 2011-07-14T22:08:41.163 回答