问题
In Python, a variable or literal followed by a hanging comma is a one-tuple
:
1, # (1,)
...and a series of comma-separated variables/literals (whether or not they are followed by a hanging comma) is also a tuple
:
1,2, # (1,2)
1,2 # (1,2)
However, inside a callable/function, this syntax is treated differently, because the comma is used for separation of arguments:
bool(5>6,) # False - 5>6 == False
bool((5>6,)) # True - (5>6,) is a non-empty tuple (always True - contents ignored)
The first line seems to simply ignore the hanging comma. The second line creates a one-tuple
(as expected). This holds true for user-defined functions as well (don't know why it wouldn't):
def f(arg):
pass
f(1,) # No Error
Consider also the following behavior of assert
(which is a statement, not a function):
assert 5>6 # AssertionError, as expected
assert(5>6) # AssertionError, as expected
assert 5>6, # SyntaxError: invalid syntax
assert(5>6,) # SyntaxWarning: assertion always true, perhaps remove parentheses?
assert 5>6, 'NOPE!' # AssertionError: NOPE!, as expected
Therefore my interpretation of the treatment of hanging commas is as follows:
- If the comma is in the context of function arguments, it is ignored
- If the comma is in the context of a statement, it is a syntax error
- Elsewhere, it is interpreted as part of a
tuple
object
My question: is my interpretation of the above behavior correct? Does the Python interpreter simply ignore hanging commas found in argument lists? Does this behavior vary by Python implementation? Finally: WHY is there an inconsistency in the treatment of a hanging comma at the end of a statement (syntax error) and at the end of an argument list (no syntax error)?
EDIT: After reading the answers and thinking it through a bit more, my interpretation should be amended as follows:
- The hanging comma is ALWAYS IGNORED, except in the following two contexts
- If the hanging comma is in the context of a statement, it is a syntax error
- If the hanging comma signals a one-
tuple
However, this still leaves the question of WHY the hanging comma is not ignored for supplying arguments to statements, when they are ignored for supplying arguments to functions.
回答1:
A tuple is defined by the comma, unless the context has defined a different meaning for the comma. In that case you need to use parentheses to disambiguate what is a tuple comma and a different comma.
assert
is not a function, it is a statement, so paretheses are not part of the syntax. Commas are, so you need the parentheses to disambiguate the tuple from the comma between the assertion expression and the failure message, but you still need the comma there to define the tuple.
Both when defining a tuple and using a in a call expression, a surplus trailing comma is ignored, consistently. But you need to be aware of when you are creating a tuple and when you are using the comma for a different expression. To create a tuple, you need at least one comma, while in a call you don't need to have that comma because the call syntax is not defined by the comma operator.
From the documentation on Expression lists:
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
The trailing comma is required only to create a single tuple (a.k.a. a singleton); it is optional in all other cases. A single expression without a trailing comma doesn’t create a tuple, but rather yields the value of that expression. (To create an empty tuple, use an empty pair of parentheses:
()
.)
and from Parethesized forms:
A parenthesized form is an optional expression list enclosed in parentheses:
parenth_form ::= "(" [expression_list] ")"
A parenthesized expression list yields whatever that expression list yields: if the list contains at least one comma, it yields a tuple; otherwise, it yields the single expression that makes up the expression list.
An empty pair of parentheses yields an empty tuple object. Since tuples are immutable, the rules for literals apply (i.e., two occurrences of the empty tuple may or may not yield the same object).
Note that tuples are not formed by the parentheses, but rather by use of the comma operator. The exception is the empty tuple, for which parentheses are required — allowing unparenthesized “nothing” in expressions would cause ambiguities and allow common typos to pass uncaught.
Emphasis mine.
Finally, from the Calls documentation:
A trailing comma may be present after the positional and keyword arguments but does not affect the semantics.
回答2:
The trailing comma is consistently ignored, in any comma-seperated listing (function calls, list/dictionary literals, etc). Your assert
example is not a comma-seperated listing.
The only reason the trailing comma is needed for the one-tuple is because there would be no way to differentiate between a one-tuple and a parenthesized expression.
来源:https://stackoverflow.com/questions/30221984/comma-syntax-rationale-behind-a-hanging-comma-in-a-statement-being-a-syntaxerro