简体   繁体   中英

Where does python argument unpacking fall into the order of operations?

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

My guess is that it falls into one of the buckets above dict lookups since

func(*mydict[mykey])

does the dictionary lookup first. Is there a better chart than my initial link that goes into more detail regarding order of operations in python?

The unpacking * is not an operator; it's part of the call syntax. It's defined under Calls , where you can see that:

["," "*" expression]

… can be part of an argument_list in two different places. (The semantics are described in the paragraphs starting "If there are more positional…" and "If the syntax…".)

So it takes any expression . You can see that no operator takes a full expression as its direct argument. So, if you want to loosely consider * an operator, it binds more loosely than any operator. But just remember that it isn't actually an operator.

Also keep in mind that this was all changed in Python 3.x. But the basic idea is the same—both argument unpacking and assignment unpacking take an expression , not just a primary , and therefore loosely-speaking bind more loosely than any operator, which all take a primary or something more specific.


Meanwhile, you might want to try running the parser on your code to see what it does:

>>> 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))])"

You can see that the entire Subscript expression ends up as the starargs to the Call .

The ast module uses the Abstract Grammar rather than the one described in the reference manual. It has different names for things, and doesn't handle some things that are considered part of the grammar but actually done at a higher level than the parser, and so on—but, on the other hand, it's a lot easier to take in all at once. You can see that an expr used for starargs can be a Subscript .

As BrenBarn mentioned in the comments, the unpacking is defined as part of function calls (Python 2 and 3) and assignment statements (Python 3).

So no, it will never take part of the operator precedence because it isn't an operator.

How do I know that this won't try to unpack "mydict" in this example? Or is this something that the language parser handles.

In your example, func(*mydict[mykey]) , the specification for the function call applies. So let's try to parse that manually.

The base part is matched by the definition of call , so *mydict[mykey] is the argument_list . And in the argument list, it will be parsed as "*" expression , with mydict[mykey] being the expression. As such, the parser will never apply the unpacking first, because the grammar simply doesn't specify a case where after "*" expression another part in brackets follows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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