这是困扰我一段时间的事情:
def test (*args, **kwargs):
print target
test(foo='bar', target='baz')
我假设target='test'
在底部的 aFunc 调用中会以 kwargs 结尾(确实如此),并且我还假设 ** 会在函数调用中解包 kwargs,因此 target 将作为关键字参数存在于 aFunc 中。它没有。我知道它是以字典的形式出现的,但我需要在参数列表中解压该字典。这可能吗?简而言之,有没有办法让 *args 和 **kwargs 消失并让实际的 args 和 kwargs 进入通话?
编辑:我整理了一个案例,其中 *args 和 **kwargs 的解包可能会有所帮助:
假设我有一个打印列表的函数:
def printList (inputList=None):
print inputList
我希望能够不传递任何列表并提供默认列表:
def ensureList (listFunc):
def wrapper (inputList=None):
listFunc(inputList=inputList or ['a','default','list'])
return wrapper
@ensureList
def printList (inputList=None):
print inputList
现在我想用一个列表中继器变得更复杂一点:
@ensureList
def repeatList (inputList=None):
print inputList*2
这很好用。但现在我想要变量重复:
@ensureList
def repeatList (times, inputList=None):
print inputList*times
现在你可以说:
repeatList(5)
它将生成默认列表并重复 5 次。
当然,这会失败,因为 wrapper 无法处理 times 参数。我当然可以这样做:
@ensureList
def repeatList (inputList=None, times=1)
但是我总是必须这样做:
repeatList(times=5)
也许在某些情况下我想强制提供一个值,所以非关键字 arg 是有意义的。
当我去年第一次遇到这样的问题时,我认为一个简单的解决方案是删除对包装器的要求:
def ensureList (listFunc):
"info here re: operating on/requiring an inputList keyword arg"
def wrapper (*args, **kwargs):
listFunc(inputList=inputList or ['a','default','list'])
return wrapper
但是,这行不通。这就是为什么我想让 args 和 kwargs 真正扩展,或者我想有办法进行扩展。然后,无论我提供什么 args 和 kwargs,它们实际上都会填写参数,而不是列表和字典。包装器中的文档将解释要求。如果传入inputList,它实际上会进入,并且从包装器回调repeatList 中的inputList 将是有效的。如果您没有传入 inputList,它会在对 repeatList 的回调中使用默认列表创建它。如果您的函数不在乎,但使用了 *kwargs,它会优雅地接受它而不会出现问题。
如果以上任何一个错误(超出一般概念),我们深表歉意。我在这里打出来的,未经测试,已经很晚了。