12

http://docs.python.org/2/reference/expressions.html#operator-precedence

我的猜测是它属于 dict 查找之上的桶之一,因为

func(*mydict[mykey])

首先进行字典查找。有没有比我的初始链接更好的图表,它更详细地介绍了 python 中的操作顺序?

4

2 回答 2

8

拆包*不是操作员;它是调用语法的一部分。它在Calls下定义,您可以在其中看到:

["," "*" expression]

… 可以是argument_list两个不同地方的一部分。(语义在“如果有更多位置……”和“如果语法……”开头的段落中描述。)

所以它需要任何expression. 您可以看到没有运算符将完整expression作为其直接参数。所以,如果你想松散地考虑*一个操作符,它比任何操作符绑定得更松散。但请记住,它实际上并不是一个运算符。

另请记住,这在 Python 3.x 中已全部更改。但基本思想是相同的——参数解包和赋值解包都采用 a expression,而不仅仅是 a primary,因此松散地说绑定比任何运算符都更松散,它们都采用 aprimary或更具体的东西。


同时,您可能想尝试在您的代码上运行解析器以查看它的作用:

>>> 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表达式starargsCall.

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

于 2013-10-22T18:34:31.087 回答
4

正如 BrenBarn 在评论中提到的,解包被定义为函数调用(Python 2 和 3)和赋值语句(Python 3)的一部分。

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

我怎么知道在这个例子中这不会尝试解压“mydict”?或者这是语言解析器处理的东西。

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

基础部分与 的定义相匹配call,. 并且在参数列表中,它将被解析为,是表达式。因此,解析器永远不会首先应用解包,因为语法根本没有指定括号中的另一个部分后面跟随的情况。*mydict[mykey]argument_list"*" expressionmydict[mykey]"*" expression

于 2013-10-22T18:32:17.090 回答