Gar*_*ler 6 python arguments kwargs
这件事现在让我误解了一段时间:
def test (*args, **kwargs):
print target
test(foo='bar', target='baz')
Run Code Online (Sandbox Code Playgroud)
我认为target='test'在底部的aFunc调用最终会出现在kwargs中(并且确实如此),并且我还假设**会在函数调用中解包kwargs,因此target将作为aFunc中的关键字参数存在.它没有.我知道它作为一个dict出现,但我需要在参数列表中解压缩该dict.这可能吗?简而言之,有没有办法让*args和**kwargs消失并让实际的args和kwargs进入通话?
编辑:我汇总了一个案例,其中*args和**kwargs的解包可能会有所帮助:
假设我有一个打印列表的函数:
def printList (inputList=None):
print inputList
Run Code Online (Sandbox Code Playgroud)
我希望能够不传递任何列表并提供默认列表:
def ensureList (listFunc):
def wrapper (inputList=None):
listFunc(inputList=inputList or ['a','default','list'])
return wrapper
@ensureList
def printList (inputList=None):
print inputList
Run Code Online (Sandbox Code Playgroud)
现在我想让列表转发器变得更复杂:
@ensureList
def repeatList (inputList=None):
print inputList*2
Run Code Online (Sandbox Code Playgroud)
这很好.但现在我想要变量重复:
@ensureList
def repeatList (times, inputList=None):
print inputList*times
Run Code Online (Sandbox Code Playgroud)
现在你可以说:
repeatList(5)
Run Code Online (Sandbox Code Playgroud)
它会生成默认列表并重复5次.
当然,这会失败,因为包装器无法处理times参数.我当然可以这样做:
@ensureList
def repeatList (inputList=None, times=1)
Run Code Online (Sandbox Code Playgroud)
但后来我总是这样做:
repeatList(times=5)
Run Code Online (Sandbox Code Playgroud)
也许在某些情况下我想强制提供一个值,所以非关键字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
Run Code Online (Sandbox Code Playgroud)
但这不起作用.这就是为什么我想让args和kwargs实际扩展,或者我想有办法进行扩展.然后无论我提供什么args和kwargs,他们实际上都填写了参数,而不是列表和dict.包装器中的文档将解释需求.如果你传入inputList,它实际上会进入,并且回调到包装器中的repeatList的inputList是有效的.如果你没有传入inputList,它将在使用默认列表的repeatList的回调中创建它.如果你的功能不关心,但是使用了*kwargs,它会毫无问题地优雅地接受它.
如果上述任何一个错误(超出一般概念),请道歉.我在这里输入了它,未经测试,现在已经很晚了.
mat*_*ath 14
" 为什么不在函数调用中解压缩kwargs? " 的答案是:因为这是一个坏主意,开发函数的人不希望局部变量根据调用参数出现.
所以,这不是它的工作方式,你肯定不希望python表现得那样.
要访问target函数中的变量,您可以使用:
def test(target='<default-value>', *args, **kwargs):
print target
Run Code Online (Sandbox Code Playgroud)
要么
def test(*args, **kwargs):
target = kwargs.get('target', '<default-value>')
print target
Run Code Online (Sandbox Code Playgroud)
但是,如果你想要一个hack(仅限教育用途)解包**kwargs,你可以尝试:
def test(*args, **kwargs):
for i in kwargs:
exec('%s = %s' % (i, repr(kwargs[i])))
print target
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4675 次 |
| 最近记录: |