如何使用Python以跨平台的方式检查路径是绝对路径还是相对路径?

199

UNIX的绝对路径以'/'开头,而Windows则以字母'C:'或'\'开头。 Python是否有标准函数来检查路径是绝对路径还是相对路径?

9个回答

284

os.path.isabs 返回 True,如果路径是绝对路径,则返回 False。 如果不是。文档 表明它在 Windows 中可用(我可以亲自证实它在 Linux 上也可用)。

os.path.isabs(my_path)

3
此函数不跨平台。在Unix系统中,os.path.isabs('c:\\') 的返回值为False。 - anatoly techtonik
90
Rotfl,它应该返回False,因为C:\不是Unix系统中的绝对路径。在Unix平台上,绝对路径以“/”开头,例如“/var/custApp/”等。 :) - Marek Lewandowski
42
让任何其他人都能够清楚地理解:c:\\ 是 Unix 中一个完全有效的文件/目录名称。因此,在 Unix 系统上,它实际上是一个相对路径。因此,该函数是跨平台的,因为它考虑了 Windows 和 Unix 的特殊性。 - Lemming
7
可以的。它在不同平台上的表现不同,会针对当前平台给出正确答案。 - Kevin Cox
1
不是回答问题。要拥有跨平台规则,请使用“ntpath”或“posixpath”,而不是“os.path”。 - Shoham

52
如果你真正想要的是绝对路径,就不要费心去检查它是否是,直接使用“abspath”即可。
import os

print(os.path.abspath('.'))  # relative paths become absolute
print(os.path.abspath('C:\Users'))  # absolute paths will remain absolute

8
可能并没有回答原来的问题,但它确实是我一直在寻找但没有意识到的东西。谢谢! - mephisto

31

Python 3.4开始,pathlib可用。

In [1]: from pathlib import Path

In [2]: Path('..').is_absolute()
Out[2]: False

In [3]: Path('C:/').is_absolute()
Out[3]: True

In [4]: Path('..').resolve()
Out[4]: WindowsPath('C:/the/complete/path')

In [5]: Path('C:/').resolve()
Out[5]: WindowsPath('C:/')

3
这个答案实际上适用于Windows操作系统。Path('\tmp').is_absolute()的结果为False,而os.path.isabs('\tmp')的结果为错误的True。有人会争辩\tmp是Windows上的绝对路径,但这只适用于非常无用的“绝对路径”定义。 - Zbyl
很奇怪。Path('C:/').is_absolute() 对我来说返回False: Python 3.6.9 (默认, Jul 17 2020, 12:50:27)
from pathlib import Path Path('..').is_absolute() False Path('C:/').is_absolute() False
- ZeZNiQ
@ZeZNiQ 你忘了提到你的操作系统了。这只在Windows上是True,正如它应该的那样。 - Robert Siemer

18

9
import os.path

os.path.isabs('/home/user')
True

os.path.isabs('user')
False

3
我认为反斜杠不会起作用,至少在我的Linux系统上不行。 - Constantinius

4

实际上,我认为以上所有答案都没有解决真正的问题:跨平台路径。os.path所做的是加载与操作系统相关的“path”库。因此,解决方案是显式加载相关(操作系统)路径库:

import ntpath
import posixpath

ntpath.isabs("Z:/a/b/c../../H/I/J.txt")
    True
posixpath.isabs("Z:/a/b/c../../H/I/J.txt")
    False

@OliverZendel 我希望没有人使用这个不可靠的函数。 - Robert Siemer

2

您可以使用ospathlib库。

使用os

>>> from os.path import isabs
>>> isabc("./")
False
>>> isabc("C:/")
True

使用 pathlib
>>> from pathlib import Path
>>> Path("./").is_absolute()
False
>>> Path("C:/").is_absolute()
True

但正如@Shoham在他的回答中所说https://dev59.com/PHA75IYBdhLWcg3wYYFQ#41846670
实际上,我认为以上所有答案都没有解决真正的问题:跨平台路径。os.path所做的是加载“path”库的操作系统相关版本。因此,解决方案是显式加载相关(操作系统)路径库:

>>> import ntpath
>>> import posixpath
>>>
>>> ntpath.isabs("Z:/a/b/c../../H/I/J.txt")
>>> True
>>> posixpath.isabs("Z:/a/b/c../../H/I/J.txt")
>>> False

0

@Zbyl 在DOS下,由于生成的路径对于不同的当前目录没有变化,因此可以说它是绝对路径。我说“可以说”是因为相对于当前驱动器,生成的路径确实会发生变化!

这是DOS遗留下来的问题,因为每个驱动器都有不同的当前目录。

通过选择不同的当前驱动器,您隐式地更改了当前目录。例如,我刚刚执行了“CD”(DOS等效于pwd)

* CD
C:\Windows\System32

然后更改当前驱动器:

* t:
T:\

这是正确的,但出乎意料。由于我无法记住26个当前目录,所以我从不使用它。

还要注意CD命令已经“损坏”:

T:\ * cd c:\Windows 
T:\

当前目录(在t:上)未更改,但已在C:上更改。我们只需要更改当前驱动器即可看到:

T:\ * c:
c:\Windows *

我经常使用pushd来更改驱动器和目录:

T:\ * pushd c:\Windows\assembly                                                                                                                                                                                                     
c:\Windows\assembly * 

由于网络共享没有卷,因此没有明显的设置当前目录的方法。Pushd知道如何做。如果您执行以下操作:

pushd \\myhost\myshare\folder

DOS/Windows 将共享映射到最后一个可用的驱动器字母,通常是 Z。然后切换到您指定的文件夹。这对于需要在批处理文件位置设置当前目录运行的批处理文件特别重要。为此,我会在许多批处理文件中使用以下命令:

SETLOCAL EnableExtensions
pushd "%~dp0"

SETLOCAL 确保新映射的卷在批处理文件结束时取消映射。否则,您很快就会用完卷字母。


这个回答如何回答问题? - miken32
@miken32:在Windows中,当前目录和相对路径可能无法以跨平台兼容的方式解析。只有您能决定DOS / Windows概念中当前驱动器和当前目录以及Windows解析相对路径是否对您很重要。我不确定您在问什么。如果我的回答完全无关,请标记它。如果我的回答不清楚、不正确或者太啰嗦,请告诉我,我会尽力根据您的建议进行改进。 - Andrew Dennison
问题是“Python是否有一个标准函数来检查路径是绝对还是相对”,并且在十多年前得到了每个人的满意答复。您的答案,虽然可能是一个有趣的离题,但似乎与Python无关。 - miken32

-3

如果你不在当前工作目录中,还有另一种方法,可能有点不太规范,但对我来说有效。

import re
path = 'my/relative/path'
# path = '..my/relative/path'
# path = './my/relative/path'

pattern = r'([a-zA-Z0-9]|[.])+/'
is_ralative = bool(pattern)

1
你的代码实际上没有使用该模式,也没有对path变量进行任何操作。 - user3064538

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接