http://docs.python.org/2/reference/expressions.html#operator-precedence
我的猜测是它落入dict查找以上的一个桶中,因为
func(*mydict[mykey])
首先查找字典。 有没有比我的初始链接更好的图表,更详细地介绍了python中的操作顺序?
答案 0 :(得分:4)
解包*
不是运营商;它是调用语法的一部分。它在Calls下定义,您可以在其中看到:
["," "*" expression]
...可以在两个不同的地方成为argument_list
的一部分。 (语义在开头“如果有更多位置......”和“如果语法......”的段落中描述。)
所以它需要expression
。您可以看到没有运算符将完整的expression
作为其直接参数。因此,如果您想松散地考虑*
运算符,它会比任何运算符更松散地绑定。但请记住,它实际上并不是一个操作员。
另请注意,Python 3.x中的所有内容都已更改。但基本思想是相同的 - 参数解包和赋值解包都需要expression
,而不仅仅是primary
,因此松散地说松散比任何运算符都松散,所有运算符都取{{1}或者更具体的东西。
与此同时,您可能希望尝试在代码上运行解析器以查看它的作用:
primary
您可以看到整个>>> 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))])"
表达式最终为Subscript
starargs
。
Call
模块使用Abstract Grammar而不是参考手册中描述的模块。它有不同的名称,并没有处理一些被认为是语法的一部分但实际上比解析器更高级别的东西,等等 - 但另一方面,它更容易被接受一次全部。您可以看到用于ast
的{{1}}可以是expr
。
答案 1 :(得分:3)
正如BrenBarn在评论中提到的那样,解包被定义为function calls(Python 2和3)和assignment statements(Python 3)的一部分。
所以不,它永远不会占用运算符优先级,因为它不是运算符。
我怎么知道在这个例子中这不会尝试解包“mydict”?或者这是语言分析器处理的东西。
在您的示例func(*mydict[mykey])
中,函数调用的规范适用。所以让我们尝试手动解析。
基本部分与call
的定义相匹配,因此*mydict[mykey]
是argument_list
。在参数列表中,它将被解析为"*" expression
,其中mydict[mykey]
是表达式。因此,解析器将永远不会首先应用解包,因为语法只是没有指定括号中"*" expression
之后的另一部分的情况。