Windows 中 os.path.join 的不可预测结果

Posted

技术标签:

【中文标题】Windows 中 os.path.join 的不可预测结果【英文标题】:Unpredictable results from os.path.join in windows 【发布时间】:2011-06-26 07:25:43 【问题描述】:

所以我想做的是以

的形式加入一些东西
os.path.join('C:\path\to\folder', 'filename'). 

**编辑: 实际代码是:

filename = 'creepy_%s.pcl' % identifier
file = open(os.path.join(self.cache_dir, filename), 'w')

其中 self.cache_dir 是使用 configobj(返回字符串)从文件中读取的,在特定情况下是 '\Documents and Settings\Administrator\creepy\cache'

第一部分是使用 configobj 从配置文件返回的。第二个是 2 个字符串的串联,例如:'file%s' % name

当我使用安装的 python 解释器通过 Windows 中的控制台运行应用程序时,我得到了预期的结果,即

C:\\path\\to\\folder\\filename 

当我将相同的应用程序和 python 解释器(相同版本,2.6)捆绑在 Windows 中的可执行文件中并运行该应用程序时,结果是

C:\\path\\to\\folderfilename

关于可能是什么问题或什么会导致输出中出现这种不一致的任何线索?

【问题讨论】:

剪切并粘贴导致问题的确切代码行。您拥有的代码行无法生成列出的输出。您示例的输出是'C:\\path\to\x0colder\\filename',它实际上在文件名之前有正确的连接反斜杠。 好吧,我只是想证明结果是正确的。可能是因为我很幸运没有任何以 f 或 t e.t.c 开头的文件夹或文件名。原代码见上文 【参考方案1】:

您的代码格式错误。您需要将这些反斜杠加倍或使用原始字符串。

os.path.join('C:\\path\\to\\folder', 'filename'). 

我不知道为什么它在一个解释器中起作用,而在另一个解释器中不起作用,但是您的代码将无法按原样正确解释。奇怪的是,我本以为会有不同的输出,即:C:pathtofolder\filename

【讨论】:

问题是它是同一个解释器。在一种情况下,它可以正常访问,在另一种情况下,它被捆绑为应用程序中的 dll。 “奇怪的是我本以为会有不同的输出”:是的,这就是奇怪的部分。但是,添加第二个反斜杠仍然可以正常工作。 好吧,\t 是一个制表符,所以区别可能只是 DLL 或 shell 的不同部分阻塞了解释器版本。也许问题是您的配置处理程序对输入进行了清理,这与您手动输入不同。 我不这么认为,configobj 吐出字符串。在任何情况下,我都不会手动输入任何内容,我只是使用 python myapp.py 运行应用程序,而不是运行 myapp.exe 。完全相同的代码,具有相同的配置文件。 当时可能链接了错误的 DLL。也许它是从系统路径加载的?你试过在编译好的exe中输出python版本吗?【参考方案2】:

这是令人惊讶的行为。没有理由它应该以这种方式行事。

请注意,您可以将行更改为以下内容。

os.path.join(r'C:\path\to\folder\', 'filename'). 

注意r'' 原始字符串和最后的\

【讨论】:

在使用os.path.join 时不需要尾部反斜杠——这就是它的用途。 :-) @Ben,我阅读了 ntpath.py 代码并发现它检查 path[-1] char,如果它是 '\',它会将下一个 arg 附加到路径中。这就是海报所要寻找的。​​span> ——-1 检查只是为了防止r"foo\"r"\bar" 作为r"foo\\bar" 加入。 os.path.join("foo", "bar") 将返回 r"foo\bar"【参考方案3】:

你可以做三件事:

    在原始字符串“C:\\path\\to\\folder”中使用双斜杠

    使用原始字符串,r'C:\path\to\folder'

    使用正斜杠,'C:/path/to/folder'

【讨论】:

嘿,感谢您的建议。正斜杠和双斜杠有效,但我仍然从配置文件或从 os.environ 获得目录的第一部分。所以,我猜想再做一些工作来添加第二个反斜杠。【参考方案4】:

我昨天想通了。像往常一样,当事情看起来很奇怪时,解释很简单,而且大多数时候你是愚蠢的。

长话短说,dist-packages 中有一些以前安装的遗留物。捆绑的解释器从那里加载模块,但是当我从终端运行 python 脚本时,当前目录中的模块(较新版本)被加载。因此,“不可预测”的结果。

【讨论】:

以上是关于Windows 中 os.path.join 的不可预测结果的主要内容,如果未能解决你的问题,请参考以下文章

os.path.join最大好处是兼容windows和linux系统,频繁需要的操作

python的os.path.join()

os.path.join 与 str 子类

python文件操作

python中使用os.path.join()

Python中join函数和os.path.join用法