Python Literal r'\'不被接受

Alf*_*lfe 19 python syntax syntax-error literals

r'\'在Python中不能按预期工作.它不会返回一个带有一个字符(反斜杠)的字符串,而是引发一个SyntaxError.r"\"做同样的事.

如果你有一个像这样的Windows路径列表,这是相当麻烦的:

paths = [ r'\bla\foo\bar',
          r'\bla\foo\bloh',
          r'\buff',
          r'\',
          # ...
        ]
Run Code Online (Sandbox Code Playgroud)

有没有理由不接受这个文字?

Sve*_*ach 27

这符合文档:

当存在'r''R'前缀时,字符串中包含反斜杠后面的字符不会更改,并且所有反斜杠都保留在字符串中.例如,字符串文字r"\n"由两个字符组成:反斜杠和小写字母'n'.字符串引号可以使用反斜杠进行转义,但反斜杠仍保留在字符串中; 例如,r"\""是一个有效的字符串文字,由两个字符组成:反斜杠和双引号; r"\"不是有效的字符串文字(即使原始字符串不能以奇数个反斜杠结尾).具体来说,原始字符串不能以单个反斜杠结尾(因为反斜杠会转义以下引号字符).另请注意,后跟换行符的单个反斜杠被解释为字符串的一部分,而不是行连续符.

使用"\\"替代,或者甚至更好,使用/的路径分隔符(是的,这适用于Windows).

  • @Alfe:简化词法分析器并非无用.只需看看你自己帖子中的语法着色,就可以看到以`\`结尾的字符串文字的负面影响.这是一个设计决定,但如果没有进一步的见解,我不会称之为糟糕.另一方面,决定在DOS和Windows中使用`\`作为路径分隔符*是一个错误的决定,至少在后见之明.幸运的是,你也可以在Python中使用`/`. (4认同)

Nik*_* B. 12

反斜杠可用于使以下引号不终止字符串:

>>> r'\''
"\\'"
Run Code Online (Sandbox Code Playgroud)

所以r'foo\'或者r'\'是未终止的文字.

合理

因为您特别询问了此设计决策背后的原因,相关方面可能如下(当然,这完全基于推测):

  • 简化了Python解释器本身的lexing(所有字符串文字具有相同的语义:结尾引号后面没有奇数个反斜杠终止字符串)
  • 简化lexing的语法高亮引擎(这是一个很有争议的论点,因为大多数编程语言都没有原始字符串仍然用单引号或双引号括起来,并且很多语法高亮引擎都被严重破坏,因为它们使用不正确的工具,如正则表达式来做乐兴)

所以是的,有可能选择这种方式的重要原因,即使你不同意这些,因为你认为你的具体用例更重要.然而,由于以下原因,它不是:

  • 您可以使用普通的字符串文字并转义反斜杠或从原始文件中读取字符串
  • 在以下两种情况之一中通常需要字符串文字中的反斜杠:
    • 您将字符串作为输入提供给另一个语言解释器,该解释器使用反斜杠作为引号字符,如正则表达式.在这种情况下,您不需要在字符串末尾添加反斜杠
    • 您正在使用\路径分隔符,这通常是不必要的,因为Python支持/Windows上的路径分隔符,因为它是os.path.sep.

解决方案

你可以使用'\\'"\\"代替:

>>> print("\\")
\
Run Code Online (Sandbox Code Playgroud)

或者,如果你完全疯了,你可以使用原始字符串文字,并将它们与普通文字结合起来,仅用于结尾反斜杠,甚至可以使用字符串切片:

>>> r'C:\some\long\freakin\file\path''\\'
'C:\\some\\long\\freakin\\file\\path\\'
>>> r'C:\some\long\freakin\file\path\ '[:-1]
'C:\\some\\long\\freakin\\file\\path\\'
Run Code Online (Sandbox Code Playgroud)

或者,在您的特定情况下,您可以这样做:

paths = [ x.replace('/', '\\') for x in '''

  /bla/foo/bar
  /bla/foo/bloh
  /buff
  /

'''.strip().split()]
Run Code Online (Sandbox Code Playgroud)

这可以节省你在添加更多路径时输入的内容,作为额外的奖励.


Alf*_*lfe 0

我的问题(“为什么反斜杠不允许作为原始字符串中的最后一个字符?”)的答案实际上对我来说似乎是“这是一个设计决定”,而且是一个值得怀疑的决定。

一些答案试图推断词法分析器和一些语法荧光笔通过这种方式更简单。我不同意(而且我有一些编写解析器和编译器以及 IDE 开发的背景)。使用反斜杠没有任何特殊含义的语义来定义原始字符串会更简单。词法分析器和 IDE 都将从这种简化中受益。

目前的情况也是一个缺点:如果我想在原始字符串中引用,我无论如何都不能使用它。只有当我碰巧想要在原始字符串中加一个反斜杠后跟一个引号时,我才能使用它。

我建议改变这一点,但我也看到了破坏现有代码的问题:-/