python os.path.join在Windows上忽略第一个路径元素?
考虑以下内容:
>>> from django.conf import settings
>>> import os
>>> settings.VIRTUAL_ENV
'C:/Users/Marcin/Documents/oneclickcos'
>>> settings.EXTRA_BASE
'/oneclickcos/'
>>> os.path.join(settings.VIRTUAL_ENV,settings.EXTRA_BASE)
'/oneclickcos/'
如你所想,我既不期望也不希望将 'C:/Users/Marcin/Documents/oneclickcos'
和 '/oneclickcos/'
连接在一起后变成 '/oneclickcos/'
。
奇怪的是,再次反转路径的组成部分时,Python似乎忽略了第一个路径部分:
>>> os.path.join(settings.EXTRA_BASE,settings.VIRTUAL_ENV)
'C:/Users/Marcin/Documents/oneclickcos'
而这个操作的结果则是比较符合预期的:
>>> os.path.join('/foobar',settings.VIRTUAL_ENV,'barfoo')
'C:/Users/Marcin/Documents/oneclickcos\\barfoo'
当然,我是在Windows系统上(Windows 7),使用的是原生的Python。
这到底是为什么呢?我该怎么解决这个问题呢?
2 个回答
4
从第二个字符串中去掉开头的 /
:
>>> os.path.join('C:/Users/Marcin/Documents/oneclickcos', 'oneclickos/')
'C:/Users/Marcin/Documents/oneclickcos\\oneclickos/'
这是因为 os.path.join
一旦遇到绝对路径,就会把之前的所有部分都丢掉,而 /oneclickos/
就是一个绝对路径。
下面是 os.path.join
文档中的一段摘录:
智能地连接一个或多个路径部分。如果任何部分是绝对路径,之前的所有部分(在Windows上,包括之前的驱动器字母,如果有的话)都会被丢弃,然后继续连接。 [...]
8
这基本上就是 os.path.join
的定义(引用自文档):
如果任何一个部分是绝对路径,那么之前的所有部分(在Windows上,包括之前的驱动器字母,如果有的话)都会被丢弃。
我觉得这样通常是个好事,因为它可以避免生成无效的路径。如果你想避免这种情况,就不要给它绝对路径。没错,以斜杠开头的路径就算是绝对路径。一个简单粗暴的解决办法就是去掉开头的斜杠(如果你想用代码实现,可以用 settings.EXTRA_BASE.lstrip('/')
)。