Windows上的Python os.path.join

时间:2010-03-11 05:38:19

标签: python windows path-manipulation

我正在尝试学习python并正在编写一个将输出脚本的程序。我想使用os.path.join,但我很困惑。根据{{​​3}},如果我说:

os.path.join('c:', 'sourcedir')

我得到"C:sourcedir"。根据文档,这是正常的,对吗?

但是当我使用copytree命令时,Python会以所需的方式输出它,例如:

import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)

这是我得到的错误代码:

WindowsError: [Error 3] The system cannot find the path specified: 'C:src/*.*'

如果我用os.path.join包裹os.path.normpath,我会收到同样的错误。

如果不能以这种方式使用os.path.join,那么我对其目的感到困惑。

根据Stack Overflow建议的页面,不应该在连接中使用斜杠 - 这是正确的,我假设?

11 个答案:

答案 0 :(得分:101)

为了更加迂腐,最蟒蛇一致的答案将是:

mypath = os.path.join('c:', os.sep, 'sourcedir')

因为你还需要os.sep作为posix根路径:

mypath = os.path.join(os.sep, 'usr', 'lib')

答案 1 :(得分:46)

Windows为每个驱动器提供了当前目录的概念。因此,"c:sourcedir"表示当前C:目录中的“sourcedir”,您需要指定一个绝对目录。

其中任何一个应该可以工作并给出相同的结果,但我目前还没有启动Windows VM进行双重检查:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")

答案 2 :(得分:11)

os.path.join('C:', 'src')无法正常工作的原因是因为您链接到的文档中存在某些内容:

  

请注意,在Windows上,因为有一个   每个驱动器的当前目录,   os.path.join(“c:”,“foo”)代表一个   相对于当前目录的路径   在驱动器C:(c:foo),而不是c:\ foo。

正如鬼狗所说,你可能想要mypath=os.path.join('c:\\', 'sourcedir')

答案 3 :(得分:9)

要迂腐,将/或\作为路径分隔符进行硬编码可能并不好。也许这会是最好的?

mypath = os.path.join('c:%s' % os.sep, 'sourcedir')

mypath = os.path.join('c:' + os.sep, 'sourcedir')

答案 4 :(得分:5)

我会说这是一个(windows)python bug。

为何选择bug?

我认为这句话应该是True

os.path.join(*os.path.dirname(os.path.abspath(__file__)).split(os.path.sep))==os.path.dirname(os.path.abspath(__file__))

但是在Windows机器上它是False

答案 5 :(得分:4)

对于在Windows和Linux上均可使用的与系统无关的解决方案,无论输入路径如何,都可以使用os.path.join(os.sep, rootdir + os.sep, targetdir)

在Windows上:

>>> os.path.join(os.sep, "C:" + os.sep, "Windows")
'C:\\Windows'

在Linux上:

>>> os.path.join(os.sep, "usr" + os.sep, "lib")
'/usr/lib'

答案 6 :(得分:3)

加入Windows路径,尝试

mypath=os.path.join('c:\\', 'sourcedir')
基本上,你需要转义斜杠

答案 7 :(得分:3)

您有几种可能的方法来处理Windows上的路径,从最硬编码的路径(如使用原始字符串文字或转义反斜杠)到最少的路径。以下是一些可以按预期工作的示例。使用更符合您需求的东西。

Day

答案 8 :(得分:0)

同意@georg -

我会说为什么我们需要跛脚os.path.join - 最好使用str.joinunicode.join,例如

sys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))

答案 9 :(得分:0)

回答您的评论:“其他'//''c:','c:\\'不起作用(C:\\创建了两个反斜杠,C:\根本不起作用)”

在Windows上使用 os.path.join('c:', 'sourcedir') 会在 sourcedir 前面自动添加两个反斜杠 \\

要解析路径,因为python在Windows上也可以使用正斜杠-> '/',只需添加 .replace('\\','/') {{ 1}} ,如下所示:-

os.path.join

例如: os.path.join('c:\\', 'sourcedir').replace('\\','/')

输出: 'C:/ temp'

答案 10 :(得分:0)

提出的解决方案很有趣并且可以提供很好的参考,但是它们只是部分令人满意。当您遇到单个特定情况或知道输入字符串的格式时,可以手动添加分隔符,但是在某些情况下,您可能希望对通用输入进行编程编程。

经过一些试验,我相信标准是,如果第一段是驱动器号,则不添加路径定界符,这意味着单个字母后跟一个冒号,无论它是否对应于真实单位。 / p>

例如:

import os
testval = ['c:','c:\\','d:','j:','jr:','data:']

for t in testval:
    print ('test value: ',t,', join to "folder"',os.path.join(t,'folder'))
test value:  c: , join to "folder" c:folder
test value:  c:\ , join to "folder" c:\folder
test value:  d: , join to "folder" d:folder
test value:  j: , join to "folder" j:folder
test value:  jr: , join to "folder" jr:\folder
test value:  data: , join to "folder" data:\folder

测试标准并应用路径校正的便捷方法是使用os.path.splitdrive,将返回的第一个元素与测试值进行比较,例如t+os.path.sep if os.path.splitdrive(t)[0]==t else t

测试:

for t in testval:
    corrected = t+os.path.sep if os.path.splitdrive(t)[0]==t else t
    print ('original: %s\tcorrected: %s'%(t,corrected),' join corrected->',os.path.join(corrected,'folder'))
original: c:    corrected: c:\  join corrected-> c:\folder
original: c:\   corrected: c:\  join corrected-> c:\folder
original: d:    corrected: d:\  join corrected-> d:\folder
original: j:    corrected: j:\  join corrected-> j:\folder
original: jr:   corrected: jr:  join corrected-> jr:\folder
original: data: corrected: data:  join corrected-> data:\folder

可以改进它,使其对尾随空间更健壮,我仅在Windows上对其进行了测试,但我希望它能给出一个主意。 另请参阅Os.path : can you explain this behavior?,以获取有关Windows以外的其他系统的有趣信息。