HOWTO · Python
在 Python 中扫描字符串文字时的 EOL 错误
在 Python 中,字符串末尾的反斜杠可能会转义看似结束字符串的引号,导致 EOL 扫描字符串文字错误;这是此类错误的一种常见原因。
本页内容
旧版诊断 EOL while scanning string literal 表示 Python 解析字符串时到达了行尾,而字符串仍未闭合。较新的 Python 版本可能会将同一问题称为未终止的字符串文字,因此具体措辞取决于解释器版本。一个常见原因是反斜杠紧挨着看似结束字符串的引号:反斜杠会转义该引号,解析器便会继续寻找字符串的结尾。
开头引号没有配对,或两侧引号不匹配,也会使字符串保持未闭合。请先检查错误指出的源代码行,再核对字符串的起始和结束定界符,以及结束定界符前的反斜杠。
EOL 字符串文字错误的含义
Python 用引号标记字符串的开头和结尾。在普通字符串中,反斜杠用于引入转义序列;\\ 表示一个实际的反斜杠。引号前若有奇数个反斜杠,该引号就会被转义,因而不能结束字符串。即使代码行看起来包含结束引号,解析器仍可能报告字符串行尾错误。
例如,行内片段 path = "C:\logs\" 中的引号被转义了。这里特意将它作为行内文本展示,因为它不是有效的 Python 代码,不能作为完整示例运行。关键是区分源代码的写法和 Python 创建的值:源代码中的反斜杠数量必须与目标值相符。
为什么原始字符串不能以反斜杠结尾
r 或 R 前缀会让 Python 在字符串值中保留反斜杠,而不解释大多数转义序列,但它不会改变引号定界规则。在解析原始字符串的源代码时,反斜杠仍然可以转义引号。因此,r"C:\logs\" 无效:最后的反斜杠转义了看似结束字符串的引号,导致字符串未闭合。
原始字符串末尾不能有奇数个反斜杠。末尾有偶数个反斜杠的原始字符串可能有效,但结果值中会保留这些反斜杠;它无法表示恰好以一个反斜杠结尾的值。需要时,可以将适合使用原始写法的部分写成原始字符串,再另行追加一个经过转义的反斜杠。
修复字符串文字
如果目标值要以一个反斜杠结尾,可以在普通字符串中转义最后一个反斜杠,也可以在末尾本身没有反斜杠的原始字符串后追加一个。这两个赋值产生的实际字符串值是 C:\logs\:logs 前有一个反斜杠,末尾也有一个反斜杠。repr 会把这个值显示为 'C:\\logs\\',将每个反斜杠加倍以便看清:
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
folder = "C:\\logs\\"
raw_folder = r"C:\logs" + "\\"
print(repr(folder))
print(repr(raw_folder))
'C:\\logs\\'
'C:\\logs\\'
repr 会在显示的值中明确展示反斜杠。第一个赋值在源代码中为值里的每个反斜杠写两个反斜杠。第二个赋值将目录部分保留为易读的原始字符串,再用普通字符串文字添加最后一个反斜杠。对于路径,如果需要组合或处理路径组成部分,请优先使用路径处理库;这些示例只用于说明 Python 如何解析字符串文字。
检查引号并验证修复
如果反斜杠数量看起来正确,请检查开头和结尾的引号是否匹配。例如,message = "That string ends here' 以双引号开头,却没有对应的双引号结尾。Python 不会把撇号当作它的结束定界符。可以将源代码改为 message = "That string ends here",或在整个字符串两侧使用匹配的单引号。
如果诊断仍然存在,可以按以下步骤检查:
- 找到报错所指的行,并确定开头的引号。
- 确认字符串在行尾之前由匹配的引号闭合。
- 数一下该引号前连续的反斜杠;奇数个反斜杠会转义引号。
- 如果目标值要以一个反斜杠结尾,请使用带转义反斜杠的普通字符串,或在原始字符串后追加一个反斜杠。
- 再次运行修正后的源代码;如果仍有其他语法错误,请查看新的诊断位置。
引用的短语有助于查找较早的讨论和示例,但应以你所用 Python 版本的实际行为和诊断措辞为准。字符串成功解析后,如果反斜杠的数量或位置不清楚,可以用 repr 检查它的值。