为什么在Python 3中,四个引号会产生语法错误?

3

我可以往三引号字符串的开头添加额外的引号,但无法在结尾处添加。为什么会这样?以下是代码块:

print(""""
String that starts with quadruple quotes and ends with triple quotes
""")

生成以下输出:
"
String that starts with quadruple quotes and ends with triple quotes

然而这段代码无法正常工作:

print(""""
String that starts with quadruple quotes and ends with quadruple quotes
"""")

它会产生以下错误:
  File "example.py", line 3
    """")
        ^
SyntaxError: EOL while scanning string literal

我从未需要使用四个引号的字符串,但我很好奇为什么Python不允许我这样做。有人能帮助我理解吗?


4
Python如何知道您希望将四个""""结尾处的第一个"作为值的一部分,而不是作为结束字符串的分隔符的一部分? - Martijn Pieters
5个回答

9

在三引号字符串的值中,无论是开头还是结尾,都不能使用"""

这是因为,在第一个三个"""开头字符表示此类字符串的开始后,另一个序列的"""始终会成为字符串的结尾。总是。您的第四个"位于创建的字符串对象之外,没有关闭的"的单个"不是有效的字符串。

Python没有其他方法知道这种字符串何时结束。您不能在最终的"""之前任意向内扩展字符串以添加其他"字符,因为那将与有效且合法的字符串*无法区分:

>>> """string 1"""" string 2"
'string 1 string 2'

如果您必须在结束的"""之前包含",请进行转义。您可以在其前面添加反斜杠来实现:
>>> """This is triple-quoted string that
... ends in a single double quote: \""""
'This is triple-quoted string that\nends in a single double quote: "'

请注意,不存在所谓的“四重引号字符串”。Python不允许您将引号"随意组合成更长的序列。只有"单引号""""三引号"""语法存在(使用"')。三引号字符串的规则与单引号字符串不同;前者允许换行,后者不允许。
请参阅参考文档中的字符串和字节文字部分以获取更多详细信息,其中定义了语法为:
shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''" | '"""' longstringitem* '"""'

并明确提到:

在三引号文字中,允许使用未转义的换行符和引号(并保留它们),但是如果连续出现三个未转义的引号,则终止文字。(“引号”是用于打开文字的字符,即'"。)

(粗体强调为本人添加)。


* 这个表达式是合法的,因为它由两个字符串字面量组成,一个使用"""引用,另一个使用"引用。连续的字符串字面量会自动连接,就像在C语言中一样。请参见字符串字面量连接


这是一个非常棒的答案。谢谢你。 - bpep
嗨。我想要看到完美的文档。抱歉,但对我来说,在文档中定义三引号文字是薄弱和不完美的。我在我的(重复的)[问题](https://stackoverflow.com/questions/76036574/why-does-the-literal-string-seven-quotes-give-an-error?noredirect=1#comment134119166_76036574)中已经给出了解释。从正式的角度来看,连续7个引号是有效的。是或否?如果你有一点时间,你能否重新审视一下那个文档章节? - Vasyl Kolomiets
请检查一下 """"a"""". 实际上,我可以在字面量的开头使用 4",它会给出 '"a'。 而 8" 被处理了,我不知道是怎么处理的,但它并不会产生错误 - 它只是一个空字符串。 - undefined

3

它被解析为三引号文本三引号引号(首先按最大匹配规则使用三引号)。您可以转义四个引号中的第一个以解决此问题。


谢谢,这个回答让我恍然大悟。你的解决方案对我很有用。 - bpep

1
一个三引号字符串字面量以一系列3个未转义的匹配引号结束。
当一个字符串字面量以4个引号开始时,前3个引号开始一个三引号字符串字面量,下一个引号只是字符串的一部分,因为必须有三个引号连续才能结束字符串。
当你试图用4个引号结束一个字符串字面量时,前三个引号结束了字符串字面量,第4个引号开始了一个新的字符串。新字符串字面量没有结束引号,这是一个语法错误。

1
你会遇到一个错误,因为你没有关闭第二组引号。
在字符串开头,你有四个引号。其中三个打开了字符串。下一个引号包含在字符串中,因为它后面没有另外两个引号。
在字符串结尾,你有四个引号。其中前三个结束了字符串。第四个打开了一个新的单引号字符串。由于你没有在行末关闭该字符串,因此会出现错误。
(实际上,在两个字符串字面值紧挨着的情况下并不会出错。Python将在编译时将它们连接起来。)

我从来不需要使用四重引号字符串,但我很好奇为什么 Python 不让我这样做。

因为四重引号字符串不是一种东西。Python 不允许你这样做,因为它没有被设计成这样。你可以有单引号字符串和三重引号字符串。任何其他数量的引号都是错误的。

感谢您深入的解释。这让我很有道理。 - bpep

-1
很不幸的是,我并没有得到为什么会有四个连续的撇号的直接实现的答案,而是得到了一个关于如何使用转义来实现直接实现的答案,或者大致上是这样回答的:“因为它就是这样实现的”。我觉得我找到了答案。这是因为Python中的另一个操作——两个直接实现的连接而不使用“+”符号。例如,“F”“A” == “F”“A” == “FA”。因此,连续8个撇号的直接实现“”“”“”“”可以有不同的解释。顺便说一下,令人惊讶的是,现在连续8个撇号不会产生错误,而是返回一个空的直接实现。

关于允许连续字符串文字的问题已经在Martijn Pieters的回答中涵盖了... 另外,你没有直接回答这里提出的问题,而是回答了一个与之相关的问题。 - undefined

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