【问题标题】:python os.path.join on windows ignores first path element?windows上的python os.path.join忽略第一个路径元素?
【发布时间】:2011-12-13 11:56:42
【问题描述】:

考虑以下几点:

>>> 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。

为什么会发生这种情况,我该怎么办?

【问题讨论】:

    标签: python windows path operating-system


    【解决方案1】:

    os.path.join 的定义大致如此(引用docs):

    如果任何组件是绝对路径,则所有先前的组件(在 Windows 上,包括先前的驱动器号,如果有的话)都将被丢弃

    我会说这通常是一件好事,因为它避免了创建无效路径。如果您想避免这种行为,请不要提供绝对路径。是的,以斜杠开头的就是绝对路径。一个快速而肮脏的解决方案只是删除前导斜杠(settings.EXTRA_BASE.lstrip('/'),如果您想以编程方式执行此操作)。

    【讨论】:

    • 好的,谢谢,但在什么意义上,'/foo/' 是 Windows 上的绝对路径?这让我感到惊讶,而且行为与平台不一致。
    • 这是一个绝对驱动路径。保留第一个元素的驱动器号实际上是有意义的: os.path.join('C:\\Users\\Marcin', '\\oneclickos\\') -> 'C:\\oneclickos\\ ' 但这不是它的工作原理。
    • 如果你问我,它一点也不矛盾。以目录分隔符开头也意味着许多(所有?)其他平台上的绝对路径。您可能会反对缺少驱动器号,但我的记忆和Wikipedia 说它完全有效,只是指同一驱动器上的绝对路径。
    【解决方案2】:

    从第二个字符串中删除前导/

    >>> os.path.join('C:/Users/Marcin/Documents/oneclickcos', 'oneclickos/')
    'C:/Users/Marcin/Documents/oneclickcos\\oneclickos/'
    

    这是因为os.path.join一旦遇到绝对路径就会丢弃所有之前的组件,而/oneclickos/是绝对路径

    这是os.path.join的文档的摘录:

    智能地加入一个或多个路径组件。如果任何组件是 绝对路径,所有以前的组件(在 Windows 上,包括 以前的驱动器号,如果有的话)被扔掉,并加入 继续。 [...]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-03
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 2022-11-30
      • 2011-06-14
      • 2015-09-22
      • 1970-01-01
      相关资源
      最近更新 更多