为什么不**解压函数调用kwargs?

这是现在有一段时间给我听的:

def test (*args, **kwargs):
    print target

test(foo='bar', target='baz')

我会假设在底部的aFunc调用中的target='test'最终会出现在kwargs中(我们也会这样做),并且我还会认为**会在函数调用中解压kwargs,所以target会作为关键字存在aFunc内部的参数。 它没有。 我知道它是以字典的形式出现的,但我需要在参数列表中解开这个字典。 这可能吗? 总之,有没有办法让* args和** kwargs消失,并让实际的参数和kwargs进入通话?

编辑 :我扔在一起的情况下,解包*参数和** 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次。

当然,这会失败,因为包装器无法处理时间参数。 我当然可以这样做:

@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实际扩展的原因,或者我想有一种扩展方法。 然后,无论我提供什么参数和kwargs,他们实际上都会填充参数,而不是列表和字典。 包装中的文档将解释需求。 如果你传入inputList,它实际上会进入,并且在从包装器回调repeatList的inputList中有效。 如果您没有传入inputList,它会在回调repeatList和默认列表中创建它。 如果你的功能不关心,但使用* kwargs,它会正常接受它没有问题。

如果上述任何一种错误(超出一般概念),我们抱歉。 我在这里输入了,未经测试,而且已经很晚了。


“为什么不在函数调用中解压kwargs?”的答案? 是:因为这是一个坏主意,开发函数的人不希望局部变量根据调用参数出现。

所以,这不是它的工作方式,你肯定不希望python的行为如此。

要访问函数中的target变量,您可以使用:

def test(target='<default-value>', *args, **kwargs):
    print target

要么

def test(*args, **kwargs):
    target = kwargs.get('target', '<default-value>')
    print target

但是,如果您想要黑客(仅限教育用途)解开** kwargs,您可以尝试:

def test(*args, **kwargs):
    for i in kwargs:
        exec('%s = %s' % (i, repr(kwargs[i])))
    print target

这种特殊情况的明显方式是

def test(foo=None, target=None):
    print target

test(foo='bar', target='baz')

如果要按名称访问函数内的参数,请在参数列表中明确指定它。

链接地址: http://www.djcxy.com/p/18177.html

上一篇: why doesn't ** unpack kwargs in function calls?

下一篇: How to hash *args **kwargs for function cache?