逗号语法:语句中悬挂逗号背后的基本原理是 SyntaxError

2023-12-23

在 Python 中,变量或文字后跟一个悬挂逗号是一个 -tuple:

1, # (1,)

...以及一系列逗号分隔的变量/文字(无论它们后面是否带有悬挂逗号)也是一个tuple:

1,2, # (1,2)
1,2 # (1,2)

然而,在可调用/函数内部,这种语法的处理方式有所不同,因为逗号用于分隔参数:

bool(5>6,) # False - 5>6 == False
bool((5>6,)) # True - (5>6,) is a non-empty tuple (always True - contents ignored)

第一行似乎只是忽略了悬挂的逗号。第二行创建一个 -tuple(如预期)。这对于用户定义的函数也适用(不知道为什么不会):

def f(arg):
    pass
f(1,) # No Error 

还要考虑以下行为assert(这是一个语句,而不是一个函数):

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 

因此我对悬挂逗号的处理解释如下:

  • 如果逗号位于函数参数的上下文中,则会被忽略
  • 如果逗号出现在语句的上下文中,则为语法错误
  • 在其他地方,它被解释为tuple object

我的问题:我对上述行为的解释正确吗? Python 解释器是否会简单地忽略参数列表中的悬挂逗号?此行为是否因 Python 实现而异?最后:为什么语句末尾(语法错误)和参数列表末尾(无语法错误)的悬挂逗号处理不一致?

编辑:阅读答案并进一步思考后,我的解释应修改如下:

  • 悬挂的逗号总是被忽略,除了以下两种情况
  • 如果悬挂逗号出现在语句的上下文中,则这是语法错误
  • 如果悬挂的逗号表示一个 -tuple

然而,这仍然留下了一个问题:为什么在为语句提供参数时不忽略悬挂逗号,而在为函数提供参数时却忽略悬挂逗号。


结尾的逗号是始终如一地在任何逗号分隔的列表(函数调用、列表/字典文字等)中被忽略。你的assert例子是not以逗号分隔的列表。

一元组需要尾随逗号的唯一原因是因为无法区分一元组和括号表达式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

逗号语法:语句中悬挂逗号背后的基本原理是 SyntaxError 的相关文章

随机推荐