【问题标题】:Why do I need 4 backslashes in a Python path?为什么我在 Python 路径中需要 4 个反斜杠?
【发布时间】:2013-11-12 06:04:20
【问题描述】:

当我使用 Python 3 通过subprocess.call() 启动程序时,为什么我需要在路径中添加 4 个反斜杠?

这是我的代码:

cmd = 'C:\\\\Windows\\\\System32\\\\cmd.exe'

cmd = shlex.split(cmd)

subprocess.call(cmd)

当我使用任务管理器检查启动的cmd.exe 实例的命令行时,它正确显示了路径,每个路径只有一个反斜杠分隔。


因此,我需要在 Windows 上使用它来使路径正常工作:

if platform.platform().startswith('Windows'):
    cmd = cmd.replace(os.sep, os.sep + os.sep)

有没有更优雅的解决方案?

【问题讨论】:

    标签: python list subprocess shlex


    【解决方案1】:

    部分问题在于您使用的是shlex,它实现了Unix-ish shell 使用的转义规则。但是您在 Windows 上运行,其命令外壳使用不同的规则。这说明了需要双反斜杠的一个级别(即,绕开 shlex 做的你不需要开始的事情)。

    您使用的是常规字符串而不是原始字符串 (r"...") 需要双反斜杠和 2*2 = 4。QED ;-)

    这在 Windows 上运行良好:

    cmd = subprocess.call(r"C:\Windows\System32\cmd.exe")
    

    顺便说一句,请仔细阅读subprocess.Popen() 的文档:Windows CreateProcess() API 调用需要一个字符串作为参数。相反,当您传递一个序列时,Python 会尝试通过文档中解释的规则将该序列转换为字符串。如果可行,最好在 Windows 上直接传递您想要的字符串。

    【讨论】:

    • 感谢您的详细解释。我会记下不要在 Windows 上使用 shlex.split(),只能在 Linux 上使用。
    【解决方案2】:

    当你创建字符串时,你需要将每个反斜杠加倍以进行转义,然后当字符串传递到你的 shell 时,你需要再次将每个反斜杠加倍。您可以使用原始字符串将反斜杠减半:

    cmd = r'C:\\Windows\\System32\\cmd.exe'
    

    【讨论】:

    • 这很有道理,但是如果第一对反斜杠由 Python 解释,那么第二对反斜杠是什么解释?
    • @minerz029,正如我在回答中解释的那样,shlex.split() 将反斜杠解释为转义字符。
    【解决方案3】:

    \ 具有特殊含义 - 您将其用作转义序列的一部分。将反斜杠加倍,你就有了一个文字反斜杠\

    需要注意的是,只有一对转义的反斜杠,你仍然只有一个文字反斜杠。你也需要转义那个反斜杠。

    或者,为什么不直接使用os.sep 呢?您将能够确保您的代码更具可移植性(因为它将使用系统特定的分隔符),并且您不必[直接]处理转义反斜杠。

    【讨论】:

    • os.sep?我已经编辑了我的问题以表明我需要加倍 os.sep 才能使路径正确启动。
    • 您可能会被这样卡住。 This similar question 也没有提供太多的缓解方式,除非你想走原始字符串的道路。
    【解决方案4】:

    正如 John 指出的那样,在本地访问文件时不需要 4 个斜杠。 一个需要 4 个斜线的地方是通过 SMB 或 CIFS 连接到(通常是 windows)服务器时。

    通常你只会使用 \servername\share\

    但是每个斜线都需要转义。因此,服务器名称前的 4 个斜线。

    你也可以使用 subprocess.call()

    import subprocess as sp
    sp.call(['c:\\program files\\<path>'])
    

    【讨论】:

    • 我不明白你的意思。约翰的回答说 4 个反斜杠是必需的,我没有在我的问题中的任何地方提到服务器(请参阅我的问题中的示例)。
    • 您的问题是“为什么我需要在路径中使用 4 个反斜杠?”您的示例不适合整个问题。所以我在可能性领域添加了网络路径。
    猜你喜欢
    • 2018-02-23
    • 2011-01-23
    • 1970-01-01
    • 2013-12-05
    • 2016-12-12
    • 1970-01-01
    • 2021-07-13
    • 2020-11-12
    相关资源
    最近更新 更多