为什么将 Windows 路径放入变量中不会用双斜杠替换特定的单斜杠?

Why does putting Windows path into a variable does not replace a particular single slash with a double slash?

为什么当我在 Python shell 中执行以下操作时,第二个斜线没有被双斜线替换?:

>>> p = 'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
>>> p
'M:\django\newenv\django_projects\mediaproject\mediaproject\media'

我认为这会导致我在尝试 os.listdir(p):

时遇到错误

FileNotFoundError: [WinError 3] The system cannot find the path specified: 'M:\django\newenv\django_projects\mediaproject\mediaproject\media'

或者是否有其他原因导致错误?该目录肯定存在,并且是从 Windows 文件资源管理器中复制粘贴的。

编辑:

我认为这是因为第二个斜杠在 n 字符之前,所以它被视为换行符。但是我该如何解决这个问题(在现实世界中我不会手动输入路径)?

尝试

 p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'

 os.listdir(p)

在字符串前添加 r 可防止在字符串内部进行转义序列解释。因此,该字符串仅被解释为原始字符串。

原始字符串和普通字符串的区别在于它们处理转义序列的方式。原始字符串总是将 \n 视为两个单独的字符,\ 后跟 n。另一方面,普通字符串会将 \n 视为单个字符。

EX.

raw_string = r"\n"
string = "\n"

print(len(raw_string)) 
print(len(string)) 

输出

2
1

处理评论,我认为 OP 需要一种方法来将 MEDIA_ROOT env 变量解析为脚本的内部变量。

为了这个目标,我建议尝试使用 os.environ 获取环境变量,并使用 os.path.abspath 将其解析为 python 路径。 示例代码如下:

import os
import os.path
try:
    media_root = os.path.abspath(os.environ['MEDIA_ROOT'])
except KeyError:
    media_root = None 
    # Alternatively you can just raise the exception here if you want to halt

或者,如果您的 MEDIA_ROOT 变量直接来自 django.conf.settings.MEDIA_ROOT,为了您的安心,您可以将它包装到一个 abspath 中,但我偷偷怀疑 django 已经这样做了你。

这里发生的事情是'\n'是控制字符NewLine,unicode U+0010。由于 '\d''\m' 都不是特殊的,因此它们保持不变。当您尝试打印 p:

时可能会更清楚
>>> print(p)
M:\django
ewenv\django_projects\mediaproject\mediaproject\media

显示为\\字符实际上是字符串中的单个\,而\n实际上是换行。

在字符串中插入 \ 的 2 种万无一失的方法是:

  • 持续加倍:

    p = 'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
    
  • 使用 r'...' 构造:

    p = r'M:\django\newenv\django_projects\mediaproject\mediaproject\media'
    

当你 copy/paste 一条路径时,后者会更容易。


注意,其他 \x 字符是特殊的:\a\b\f\r\t\v. 另外,'\xab'是编码ab的字符(比如'\x41'在ascii charset中是'A')'\uabcd'是unicode字符U+abcd,'\U00abcdef'是unicode字符U+abcdef.