为啥这不是python中的语法错误?

Posted

技术标签:

【中文标题】为啥这不是python中的语法错误?【英文标题】:Why isn't this a syntax error in python?为什么这不是python中的语法错误? 【发布时间】:2014-07-22 18:39:00 【问题描述】:

今天注意到我们的代码库中有一行我认为肯定会因为语法错误而导致构建失败,但测试通过了,显然它实际上是有效的 python(在 2.x 和 3 中)。

条件表达式中有时不需要空格:

>>> 1if True else 0
1

如果 LHS 是变量则不起作用:

>>> x = 1
>>> xif True else 0
  File "<stdin>", line 1
    xif True else 0
           ^
SyntaxError: invalid syntax

但它似乎仍然适用于其他类型的文字:

>>> 'hello'if False else 'potato'
'potato'

这里发生了什么,出于某种原因,它是否有意成为语法的一部分?这种奇怪的怪癖是已知/记录在案的行为吗?

【问题讨论】:

Python 名称不能以数字开头,这是原因之一。解析器知道if 是一个新令牌。 @MartijnPieters 确实如此,但这并不能真正解释到底发生了什么。 @BrandonBuck:Poke 已经找到了参考文档的相关部分,但这正是这里发生的事情。 注意:如果代码比较难理解,也可以通过tokenize、get the abstract syntax tree或disassemble代码来帮助。 【参考方案1】:

Whitespace between tokens

除了在逻辑行的开头或在字符串文字中,空白字符空格、制表符和换页符可以互换使用来分隔标记。只有当它们的连接可以被解释为不同的标记时,两个标记之间才需要空格(例如,ab 是一个标记,但 a b 是两个标记)。

所以在这种情况下,1if 不是一个有效的标记,所以空格是可选的。 1 被解释为整数文字,if 不是其中的一部分。所以if被单独解释并识别为关键字。

然而,在 xif 中,识别出一个标识符,因此 Python 无法看到您想要在那里执行 x if

【讨论】:

按这个推理,1 if 1else 0 不应该解析吗? (它没有) @wim 我有点困惑,认为它也应该解析,但1e 实际上被解释为科学记数法中文字的开头;例如1e3 == 1000 有趣!阅读您的评论后,我注意到 1 if 1jelse 0 确实 解析。 @wim: 或1 if 0b1else 01else 不解析的事实表明,此答案中引用的规则与实现并不完全一致,因为 1else 不能以其他方式解释为不同的标记,1e 也不能。 (0x1else 也不解析,但那是因为最大咀嚼规则使它变成了0x1e lse,两者都是有效的。) 我很确定这是一个错误。我会在跟踪器上提出问题。【参考方案2】:

由于我对词法处理和标记化的了解有限,我想说的是,您所看到的是任何可以从 if 被词法解析为“不同”(即数字/字典等)的片段正在这样做。大多数语言都会忽略空格,我想 Python 也会这样做(当然不包括缩进级别)。生成标记后,语法本身并不关心,它很可能会寻找 [EXPRESSION] [IF] [EXPRESSION] [ELSE] [EXPRESSION] 分组,再次使用您的示例,它可以正常工作。

【讨论】:

【参考方案3】:

Python 词法分析器为输入 1if 生成两个标记:整数 1 和关键字 if,因为以数字开头的标记不能包含字符串 if。另一方面,xif 被识别为有效标识符;没有理由相信它是一个标识符后跟一个关键字,因此作为单个标记传递给解析器。

【讨论】:

以上是关于为啥这不是python中的语法错误?的主要内容,如果未能解决你的问题,请参考以下文章

请问哈,为啥会出来invalid syntax语法错误

为啥我会收到此语法错误? (Python)

SyntaxError:python 中的语法无效,为啥? [复制]

SQL 中的 Pivot 语法错误,为啥我得到不正确的结果?

为啥 Pydev 会给出内置关键字的语法错误?

为啥我收到“UPDATE 语句中的语法错误”。例外?