Windows上的Python os.path.join

Python os.path.join on Windows

我正在尝试学习python并正在制作一个将输出脚本的程序。 我想使用os.path.join,但我很困惑。 根据文件,如果我说:

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

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

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

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

这是我得到的错误代码:

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

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

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

根据Stack Overflow建议的页面,斜杠不应该用于正确的联合,我假设?


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

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

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

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


Windows对每个驱动器都有一个当前目录的概念。因此,"c:sourcedir"在当前C:目录中表示"sourcedir",您需要指定一个绝对目录。

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

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


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

Note that on Windows, since there is a
current directory for each drive,
os.path.join("c:","foo") represents a
path relative to the current directory
on drive C: (c:foo), not c:\foo.

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


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

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

要么

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

对于适用于Windows和Linux的系统无关解决方案,无论输入路径是什么,都可以使用os.path.join(os.sep, rootdir + os.sep, targetdir)

在WIndows上:

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

在Linux上:

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


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

为什么虫子?

我认为这个陈述应该是True

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

但它在Windows机器上是False


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

1
2
3
4
5
6
7
8
9
10
11
12
In[1]: from os.path import join, isdir

In[2]: from os import sep

In[3]: isdir(join("c:","\","Users"))
Out[3]: True

In[4]: isdir(join("
c:","/","Users"))
Out[4]: True

In[5]: isdir(join("
c:", sep,"Users"))
Out[5]: True

要加入Windows路径,请尝试

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

基本上,你需要逃避斜线


同意@ georg-

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

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