110

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

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: [错误 3] 系统找不到指定的路径:'C:src/*.*'

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

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

根据 Stack Overflow 建议的页面,连接中不应使用斜杠——我认为这是正确的吗?

4

11 回答 11

140

为了更加迂腐,最python doc一致的答案是:

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

由于您还需要 os.sep 作为 posix 根路径:

mypath = os.path.join(os.sep, 'usr', 'lib')
于 2011-10-14T12:56:25.503 回答
70

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

这些中的任何一个都应该工作并给出相同的结果,但我目前没有启动 Windows VM 来仔细检查:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")
于 2010-03-11T05:52:34.950 回答
16

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

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

或者

mypath = os.path.join('c:' + os.sep, 'sourcedir')
于 2011-09-15T17:56:29.007 回答
14

原因os.path.join('C:', 'src')没有按您预期的那样工作是因为您链接到的文档中的某些内容:

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

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

于 2010-03-11T05:47:30.187 回答
14

对于适用于 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'
于 2018-07-11T01:56:37.310 回答
7

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

为什么会出错?

我认为这种说法应该是True

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

但它False在Windows机器上。

于 2013-07-01T08:09:41.353 回答
5

要加入 Windows 路径,请尝试

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

基本上,你需要避开斜线

于 2010-03-11T05:45:09.800 回答
4

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

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
于 2017-10-30T21:21:44.247 回答
1

同意@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))
于 2016-03-19T09:49:43.127 回答
0

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

通过一些实验,我认为标准是如果第一段是驱动器号,则不添加路径分隔符,这意味着单个字母后跟冒号,无论它是否对应于实际单元。

例如:

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 :您能解释一下这种行为吗?有关 Windows 以外系统的有趣详细信息。

于 2020-02-08T19:02:24.037 回答
0

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

在 windows using os.path.join('c:', 'sourcedir') 将自动在sourcedir\\前面添加两个反斜杠。

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

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

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

输出:'C:/temp'

于 2020-02-04T17:14:53.037 回答