'kwargs' 在 python 装饰器中为空

yao*_* Ge 5 python decorator

我在下面运行了一个装饰器演示。

def logger(func):
    def inner(*args, **kwargs):
        print(args)
        print(kwargs)
        return func(*args, **kwargs)
    return inner

@logger
def foo1(a, b, c, x=2, y=1):
    print(x * y)

foo1(6,7,8)
Run Code Online (Sandbox Code Playgroud)

输出是:

(6, 7, 8)
{}
2
Run Code Online (Sandbox Code Playgroud)

为什么字典是空的?我认为应该是{'x':2, 'y':1}

wow*_*in2 5

这是因为kwargs函数调用中没有提供。装饰器logger对此一无所知,也不知道将使用什么函数。kwargs它是提供的和实际调用之间的“代理” 。

请参阅下面的示例:

# kwargs are not provided (not redefined), function `foo1` will use default.
>>> foo1(6, 7, 8)
(6, 7, 8)
{}
2

# new kwargs are provided and passed to decorator too
>>> foo1(6, 7, 8, x=9, y=10)
(6, 7, 8)
{'x': 9, 'y': 10}
90
Run Code Online (Sandbox Code Playgroud)

这类似于:

def foo1(a, b, c, x=2, y=1):
    print(x * y)


def logger(func):
    def inner(*args, **kwargs):
        print(args)
        print(kwargs)
        return func(*args, **kwargs)
    return inner


wrapped_foo1 = logger(foo1)
wrapped_foo1(6,7,8)
Run Code Online (Sandbox Code Playgroud)

当你可以清楚地看到问题时,甚至可以简化为以下内容:

def foo1_decorated(*args, **kwargs):
    print(args)  # <-- here it has no chance to know that `x=2, y=1`
    print(kwargs)
    return foo1(*args, **kwargs)

foo1_decorated(6, 7, 8)
Run Code Online (Sandbox Code Playgroud)