为什么在Python中使用两个分号会导致语法错误?

68

我知道在Python中分号是不必要的,但是它们可以用于将多个语句压缩到一行上,例如:

>>> x = 42; y = 54

我一直以为分号相当于换行符。所以当我得知(h/t Ned Batchelder on Twitter)双分号是一个SyntaxError时,有些惊讶:

>>> x = 42
>>> x = 42;
>>> x = 42;;
  File "<stdin>", line 1
    x = 42;;
           ^
SyntaxError: invalid syntax

我假设上一个程序等同于x = 42\n\n。 我原以为分号之间的语句被视为空行,即无操作。 显然不是这样。 为什么会出错?

9
分号不等同于换行,否则类似if condition:;的写法也将合法,但事实并非如此。 - tobias_k
@tobias_k 不,这是不合法的。你需要一个“pass”。但是,“if condition:;pass”也不起作用。 - palsch
2
为什么不应该是一个错误呢?没有理由编写这样的代码,它很可能会让下一个读者感到困惑,因此,让它变成明确的非法操作(防止您犯错,从而让您的同事在看到代码时不知道双冒号语法的效果)对Python来说是有帮助的吧? - Mark Amery
你会期望 print [1, 2,, 3] 能够正常工作吗?这几乎是同样的事情。 - Luaan
2个回答

104

从Python语法中,我们可以看到;并没有被定义为\n。解析器期望在;之后有另一个语句,除非它后面有一个换行符:

                     Semicolon w/ statement    Maybe a semicolon  Newline
                          \/     \/               \/                \/
simple_stmt: small_stmt (';' small_stmt)*        [';']            NEWLINE

这就是为什么 x=42;; 不起作用的原因,因为两个分号之间没有语句,"nothing"不是一个语句。如果它们之间有任何完整的语句,比如一个 pass 或者只是一个 0,那么代码就能正常工作。
x = 42;0; # Fine
x = 42;pass; # Fine
x = 42;; # Syntax error

if x == 42:; print("Yes") # Syntax error - "if x == 42:" isn't a complete statement

你也可以说这是因为非终结符 small_stmt 不可为空,即空字符串(epsilon)不匹配 small_stmt。在其他语言中也是如此。 - thwd
可能有一个打字错误:语法错误 - "if x == 2:",也许应该是42? - Ron Klein

22

即使你有分号,空语句仍然需要 pass

>>> x = 42;pass;
>>> x
42

1
但是一个空行可以被解析而不需要通过,因此这个答案并没有解释换行符和分号之间的区别。 - SuperBiasedMan
3
我说的是一句空话,而不是一行空白。 - TigerhawkT3
啊,现在我明白了。可能值得更清楚地区分一下语句和行之间的区别。 - SuperBiasedMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接