【问题标题】:How to get absolute path of a pathlib.Path object?如何获取 pathlib.Path 对象的绝对路径?
【发布时间】:2017-02-28 15:44:29
【问题描述】:

使用pathlib 模块创建路径对象,例如:

p = pathlib.Path('file.txt')

p 对象将指向文件系统中的某个文件,因为我可以这样做,例如 p.read_text()

如何在字符串中获取p 对象的绝对路径?

似乎我可以使用例如os.path.abspath(p) 来获取绝对路径,但是使用os.path 方法很尴尬,因为我认为pathlib 应该是os.path 的替代品。

【问题讨论】:

  • 与您的 .py 文件相比,'file.txt' 是否作为相对路径存在?如果是,那么您需要做的就是获取“当前路径”,然后将其连接到'file.txt'
  • @TehTris: 我假设可以仅基于p 获取p 的绝对路径,因为我可以基于p 打开文件,所以位置必须已经在文件系统中修复了。

标签: python python-3.x pathlib


【解决方案1】:

使用resolve()

像这样简单地使用Path.resolve()

p = p.resolve()

这使您的路径成为绝对路径,并将所有相对部分替换为绝对部分,并将所有符号链接替换为物理路径。在不区分大小写的文件系统上,它还将规范化大小写(file.TXT 变为 file.txt)。

避免absolute()

您不应该使用 absolute(),因为它没有记录,未经测试,也没有考虑删除。 (参见@Jim Fasarakis Hilliard 创建的the bug report 中的讨论)。

区别

resolveabsolute 之间的区别在于absolute() 不会替换路径的符号链接(符号链接)部分,并且它永远不会引发FileNotFoundError。它也不修改大小写。

如果您想避免resolve()(例如,您想保留符号链接、大小写或相关部分),请改用它:

p = Path.cwd() / "file.txt"

即使您提供的路径是绝对路径,这仍然有效——在这种情况下,cwd(当前工作目录)将被忽略。

注意 Windows 上不存在的文件

如果文件不存在,在 Windows 上的 Python 3.6 到 3.9 中,resolve() 不会在当前工作目录前添加。请参阅issue 38671,已在 Python 3.10 中修复。

小心 FileNotFoundError

在 v3.6 之前的 Python 版本中,如果磁盘上不存在路径,resolve()引发FileNotFoundError

因此,如果有任何风险,请事先与p.exists() 联系或尝试/捕获错误。

# check beforehand
if p.exists():
    p = p.resolve()

# or except afterward
try:
    p = p.resolve()
except FileNotFoundError:
    # deal with the missing file here
    pass

如果您首先要处理的路径不在磁盘上,并且您不在 Python 3.6+ 上,最好恢复到 os.path.abspath(str(p))

从 3.6 开始,如果您使用 strict 参数,resolve() 只会引发 FileNotFoundError

# might raise FileNotFoundError
p = p.resolve(strict=True)

但请注意,使用 strict 会使您的代码与 3.6 之前的 Python 版本不兼容,因为这些版本不接受 strict 参数。

未来

关注issue 39090 以关注与absolute() 相关的文档更改。

【讨论】:

  • 我仍然有向后移植的问题——openpyxlwb.save_workbook()open(str, 'w') 在 Python 3.5.5 中(在 Travis CI 中)。所以,是的,这个,“在 v3.6 之前的 Python 版本上,如果磁盘上不存在路径,resolve() 确实会引发 FileNotFoundError。”不是真的。
  • @Polv 查看 3.5 的官方文档:docs.python.org/3.5/library/pathlib.html#pathlib.Path.resolve 它明确指出“如果路径不存在,则提升 FileNotFoundError。”
  • 对不起,我看错了,但是在 3.6 之前,我如何使用绝对路径 write to a new file...
  • 只是...先写入文件,然后调用resolve() 获取其规范路径?否则,请使用os.path.abspath(str(pathlib_path_object))
  • 在 Windows 上(也许在 Linux 上也是如此?),absolute() 使用任何符号链接返回路径,resolve() 返回符号链接已解析(消失)的路径。
【解决方案2】:

如果你只是想要路径而不想检查文件是否存在,你可以这样做

str(p)

作为Operations 部分中的文档。

【讨论】:

  • topic starter 要求 absolute 路径,你不能从 Path 用相对路径初始化的对象中得到它
【解决方案3】:

您正在寻找方法.absolute,如果我的理解是正确的,其文档说明:

>>> print(p.absolute.__doc__)
Return an absolute version of this path.  This function works
        even if the path doesn't point to anything.

        No normalization is done, i.e. all '.' and '..' will be kept along.
        Use resolve() to get the canonical path to a file.

在我的系统上有一个测试文件,这会返回:

>>> p = pathlib.Path('testfile')
>>> p.absolute()
PosixPath('/home/jim/testfile')

This method 似乎是对PathPath 继承对象的一个​​新的、并且仍然没有记录的补充。

Created an issue to document this.

【讨论】:

  • 当然,公认的答案就是绝对没有人应该使用的答案。另见the only sane answer, which documents exactly why this is the case
  • 我不得不使用 resolve() 函数,因为 absolute() 给了我一个像 /home/usename/projects/src/app/../../interfaces/ 这样的路径,而不是比如 /home/usename/projects/interfaces/
【解决方案4】:
pathlib.Path.cwd() / p

这是 recommended by CPython core developers 作为“一种显而易见的方式”。

p.resolve() 至少不会为 Windows 上不存在的文件返回绝对路径。

p.absolute() 未记录在案。

【讨论】:

  • 嗯,它是一个 CPython核心开发者推荐的(并且被另一个人提出异议,因为不是很明显)。此外,在同一页面上,demonstrated 该解决方案并不总是产生绝对路径。它适用于大多数情况,但不是防弹的。
猜你喜欢
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 2015-04-14
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多