python参数解包的操作顺序在哪里?

python参数解包的操作顺序在哪里?,python,Python,我的猜测是,它落入了dict查找中的一个桶中 func(*mydict[mykey]) 先查字典。 有没有比我的初始链接更好的图表,可以更详细地介绍python中的操作顺序?正如BrenBarn在评论中提到的,解包被定义为(python 2和3)和(python 3)的一部分 因此,它永远不会成为运算符优先级的一部分,因为它不是运算符 我怎么知道在这个例子中,它不会试图解包“mydict”?或者这是语言解析器处理的事情 在您的示例中,func(*mydict[mykey]),函数调用的规范适用

我的猜测是,它落入了dict查找中的一个桶中

func(*mydict[mykey])
先查字典。
有没有比我的初始链接更好的图表,可以更详细地介绍python中的操作顺序?

正如BrenBarn在评论中提到的,解包被定义为(python 2和3)和(python 3)的一部分

因此,它永远不会成为运算符优先级的一部分,因为它不是运算符

我怎么知道在这个例子中,它不会试图解包“mydict”?或者这是语言解析器处理的事情

在您的示例中,
func(*mydict[mykey])
,函数调用的规范适用。因此,让我们尝试手动解析它


基本部分与
调用
的定义匹配,因此
*mydict[mykey]
参数列表
。在参数列表中,它将被解析为
“*”表达式
,其中
mydict[mykey]
为表达式。因此,解析器永远不会首先应用解包,因为语法根本没有指定在
“*”表达式之后,括号中的另一部分紧跟其后的情况。

解包
*
不是运算符;这是调用语法的一部分。定义如下,您可以看到:

["," "*" expression]
…可以在两个不同的位置作为参数列表的一部分。(语义在“如果有更多位置…”和“如果语法…”开头的段落中描述。)

所以它需要任何
表达式
。您可以看到,没有运算符将完整的
表达式
作为其直接参数。因此,如果你想松散地考虑<代码> */Cux>一个运算符,它比任何运算符绑定得更松散。但请记住,它实际上不是一个操作员

还要记住,在Python3.x中,这一切都发生了更改。但基本思想是相同的,参数解包和赋值解包都采用
表达式,而不仅仅是
,因此,从广义上讲,绑定比任何操作符都要宽松,它们都采用
或更具体的东西


同时,您可能希望尝试在代码上运行解析器,以查看它的功能:

>>> import ast
>>> tree = ast.parse('func(*mydict[mykey])')
>>> ast.dump(tree)
"Module(body=[Expr(value=Call(func=Name(id='func', ctx=Load()), args=[], keywords=[],
starargs=Subscript(value=Name(id='mydict', ctx=Load()),
slice=Index(value=Name(id='mykey', ctx=Load())), ctx=Load()), kwargs=None))])"
您可以看到,整个
下标
表达式最终成为
调用
starargs


ast
模块使用的是,而不是参考手册中所述的。它对事物有不同的名称,并且不处理一些被认为是语法的一部分但实际上是在比解析器更高的级别上完成的事情,等等,但是,另一方面,它更容易一次全部接受。您可以看到用于
starargs
expr
可以是
下标

它不是一个操作,而是函数调用的一部分
*mydict[mykey]
本身没有任何意义,只有
func(*mydict[mykey])
导致参数解包。请注意,在Python 3中,元组解包不再是函数调用的一部分(这就是
a,*b=(1,2,3)
工作的原因,整个过程解释得更好…但这对Python2没有帮助。(另外,即使在3.x中,解包
*
到底是什么仍然不清楚。它在某些地方被称为运算符,在其他地方则明确表示不是运算符……。@abarnert在Python3中,元组解包是函数调用的一部分。唯一改变的是它现在也是赋值的一部分。啊,我明白了,所以解包是在表达式求值之后进行的。这个答案适用于Python 3。Python2中的情况并没有太大的不同,但它们是不同的。您可以使用docs页面顶部的version下拉菜单切换到您的特定版本。我看不出这是如何“在python3中全部更改”的。调用的语法基本相同,尤其是在解包本身的行为方面。@poke:callstarargs和赋值目标的语法是统一的(def varargs也是统一的)。我想这并没有多大的实际区别;不管怎样,松散的答案是“如果你把它当作一个操作符,它的优先级比任何操作符都低”,正确的答案包括阅读参考语法或抽象语法,或者使用
ast
为你做后者……你的观点是没有意义的。在Python2和Python3中,代码都会生成相同的AST,因此这些语法上的细微更改在这里并没有真正的区别,而且绝对不意味着它“在Python3中都发生了更改”-这意味着一种完全不同的行为,尽管这根本不是真的…