繁体   English   中英

解包参数:只有命名参数可以跟*表达式

[英]Unpacking arguments: only named arguments may follow *expression

以下在Python中运行得非常好:

def f(x,y,z): return [x,y,z]

a=[1,2]

f(3,*a)

的元素a得到解压缩,如果你有一个像把它称为f(3,1,2)并返回[3,1,2] 精彩!

但是我无法将a的元素解压缩到两个参数中:

f(*a,3)

我没有像f(1,2,3)那样调用它,而是“SyntaxError:只有命名参数才能跟*表达式”。

我只是想知道为什么它必须是这样的,如果有任何聪明的技巧我可能不会意识到将数组解压缩到参数列表的任意部分而不诉诸临时变量。

正如Raymond Hettinger的回答所指出的,这可能会在Python 3中发生变化, 这是一个相关的提案 ,已被接受。 特别是与当前问题有关,这是对该提案的可能变更之一:

仅允许星号表达式作为exprlist中的最后一项。 这将简化解包代码并允许为星号表达式分配迭代器。 这种行为被拒绝了,因为它太令人惊讶了。

所以有解包函数参数限制的实现原因,但确实有点令人惊讶!

与此同时,这是我正在寻找的解决方法,回顾过去有点明显:

f(*(a+[3]))

感谢PEP 448 - 附加拆包概括

f(*a, 3)

现在从Python 3.5开始接受的语法 同样,您可以在任何地方使用双星**关键字参数解压缩,并且可以多次使用其中一个。

并不一定是这样的。 Guido认为合情合理。

在Python 3中,解包的规则已经有所自由:

>>> a, *b, c = range(10)
>>> a
0
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]
>>> c
9

根据Guido是否认为它会改善语言,自由化也可以扩展到功能论点。

有关Python 3更改规则的原因的一些想法,请参阅有关扩展可迭代解包的讨论。

f期望3个参数( xyz ,按此顺序)。

假设L = [1,2] 当你调用f(3, *L) ,python在幕后做的是调用f(3, 1, 2) ,而不知道L的长度。

那么如果L代替[1,2,3]会发生什么?

然后,当你调用f(3, *L) ,你最终会调用f(3,1,2,3) ,这将是一个错误,因为f期待正好3个参数,你给它4。

现在,假设L=[1,2]1. Look at what happens when you call L=[1,2]1. Look at what happens when you call f` L=[1,2]1. Look at what happens when you call

>>> f(3,*L) # works fine
>>> f(*L) # will give you an error when f(1,2) is called; insufficient arguments

现在,你隐含地知道你何时调用f(*L, 3)将3分配给z ,但是python不知道。 它只知道f的输入的最后j元素将由L的内容定义。 但由于它不知道len(L)的值,因此无法假设f(*L,3)是否具有正确数量的参数。

然而,这不是f(3,*L) 在这种情况下,python知道除了第一个参数之外的所有参数都将由L的内容定义。

但是如果你有参数f(x=1, y=2, z=3) ,则首先绑定按名称分配的参数。 只有这样才能限制位置参数。 所以你做f(*L, z=3) 在这种情况下, z首先绑定到3 ,然后绑定其他值。

现在有趣的是,如果你做f(*L, y=3) ,这会给你一个错误,试图分配给y两次(一次用关键字,再一次用位置)

希望这可以帮助

尼斯。 这也适用于元组。 不要忘记逗号:

a = (1,2)
f(*(a+(3,)))

如果你使用f(*a, 3) ,你可以使用f(*a, z=3) ,它不知道如何解压缩参数,因为你提供了2个参数而2是第二个参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM