我在下面运行了一个装饰器演示。
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}
这是因为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)