我找到的关于装饰器的所有教程都建议在包装函数的签名中使用 *args, **kwargs
来处理来自包装函数的参数。然而 kwargs 不起作用,而普通参数则:
from functools import wraps
def wrapper(a_thing):
@wraps(a_thing)
def do_thing(*args, **kwargs):
print('before')
print(kwargs)
value = a_thing(*args, **kwargs)
print("after", *args, **kwargs)
return value
return do_thing
@wrapper
def output(*args, **kwargs):
print('during', *args, **kwargs)
import pdb; pdb.set_trace()
这是我的交互式输出:
(Pdb) output(99, 100)
before
{}
during 99 100
after 99 100
(Pdb) output(arg1=99, arg2=100)
before
{'arg1': 99, 'arg2': 100}
*** TypeError: 'arg1' is an invalid keyword argument for this function
(Pdb)
这是an example许多此类教程之一:
如果 **kwargs 不起作用,那么使用它还有什么意义呢?我感觉我失去了一些东西。
最佳答案
您不想在对 print
的调用中解包; print
仅接受有限数量的关键字参数,并拒绝所有其他参数。想必您只是想查看传递的内容,因此无需解压即可打印原始元组和字典:
def wrapper(a_thing):
@wraps(a_thing)
def do_thing(*args, **kwargs):
print('before')
print(kwargs)
value = a_thing(*args, **kwargs)
print("after", args, kwargs) # Removed unpacking
return value
return do_thing
@wrapper
def output(*args, **kwargs):
print('during', args, kwargs) # Removed unpacking
解包的要点在于,它传递 *
解包迭代的元素作为顺序位置参数,以及使用 **
解包映射中的键值对键作为关键字参数,值作为关联值。所以当你这样做时:
print('during', *args, **kwargs)
使用output(arg1=99, arg2=100)
调用函数后,就好像您运行了:
print('during', arg1=99, arg2=100)
arg1
和 arg2
都不是 print
接受的关键字,所以它对你尖叫。通过删除解包,print
等效于:
print('during', (), {'arg1': 99, 'arg2': 100})
这是完全有效的(它直接打印tuple
和dict
,而不是尝试解包)。
关于python - 用装饰器包装的函数的关键字参数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55174701/