使用pathlib规范化不存在的路径

37

Python最近添加了pathlib模块(我非常喜欢!)。

只有一件事让我感到困扰:是否可以将路径规范化为不存在的文件或目录?我可以使用os.path.normpath完成这个操作。但是,难道不应该使用应该负责处理路径相关事务的库吗?

我想要的功能是这样的:

from os.path import normpath
from pathlib import Path
pth = Path('/tmp/some_directory/../i_do_not_exist.txt')
pth = Path(normpath(str(pth)))
# -> /tmp/i_do_not_exist.txt

是否有一种只用 pathlib 的简单方法来实现,而无需使用 os.path,也无需将类型转换为 str 并再次转换为 Path。另外注意,对于不存在的文件,pth.resolve() 无法工作。


3
pathlib 本身在 .resolve() 方法中内部调用了 normpath(),因此您可能无法仅使用 pathlib 规范化不存在的路径。 - jfs
4个回答

28

能否将一个指向不存在的文件或目录的路径规范化?

从3.6开始,这是默认行为。请参阅https://docs.python.org/3.6/library/pathlib.html#pathlib.Path.resolve

Path.resolve(strict=False)
...
如果strictFalse,则会尽可能解析该路径,并将任何剩余部分附加到路径中,而不会检查其是否存在。


你可以使用pathlib2,它是最新的pathlib在pythons 2.6+上的后移版本。但是,你还应该知道这与normpath不同。由于它尽可能地解析链接,并且当前目录始终可解析,因此相对路径将始终以绝对路径结尾,无论是否真正匹配任何内容。这是同时采取两种方法的最糟糕情况,所以在该API稳定之前,除非使用strict=True,否则我建议避免使用pathlibresolve()方法。 - Mr. B
3
实际上,这与os.path.normpath()并不完全相同!首先,它会将路径转换为绝对路径(如果可能的话)。其次,它会解析符号链接(如果可能的话)! - mrh1997

9
截至Python 3.5:没有。PEP 0428指出:“路径解析”方法使路径绝对化,解析任何符号链接(类似于POSIX realpath()调用)。它是唯一删除“..”路径组件的操作。在Windows上,此方法还会注意返回规范路径(具有正确的大小写)。由于“resolve()”是唯一删除“..”组件的操作,并且当文件不存在时失败,因此仅使用“pathlib”没有简单的方法。此外,pathlib文档提供了一个提示。
虚假的斜杠和单个点会被合并,但是双点('..')不会,因为这会在符号链接面前改变路径的含义:
PurePath('foo//bar') 生成 PurePosixPath('foo/bar')
PurePath('foo/./bar') 生成 PurePosixPath('foo/bar')
PurePath('foo/../bar') 生成 PurePosixPath('foo/../bar')
(天真的方法会使PurePosixPath('foo/../bar')等同于PurePosixPath('bar'),如果foo是指向另一个目录的符号链接,则是错误的)
话虽如此,你可以在路径位置创建一个0字节的文件,然后就可以解析路径(从而消除..)。我不确定这是否比您的normpath方法更简单。

3
如果这符合您的用例(例如,文件夹已经存在),您可以尝试解析路径的父级,然后重新追加文件名,例如:
如果您使用的是该用例,则可能需要尝试“解析”路径的父级,然后重新附加文件名,例如:
from pathlib import Path

p = Path()/'hello.there'
print(p.parent.resolve()/p.name)

-1

虽然这是一个老问题,但如果您想要在整个系统中使用 POSIX 路径(例如在 Windows 上使用 nix 路径),那么这里有另一种解决方案。

我发现 Python 3.10 中的 pathlib resolve() 方法存在问题,并且该方法目前未被 PurePosixPath 暴露出来。

我发现使用 posixpath.normpath() 可以解决问题。同时,PurePosixPath.joinpath() 也存在问题。例如,它无法将 ".." 与 "myfile.txt" 连接起来,而是只会返回 "myfile.txt"。但是,posixpath.join() 却可以完美地工作,它会返回 "../myfile.txt"。

请注意,这是针对路径字符串的解决方案,但是您可以轻松地将其转换为 OOP 容器,例如 pathlib.Path(my_posix_path) 等。

如果您需要在 Windows 平台上使用该解决方案,只需按照此方式构建即可,因为该模块会自动处理平台独立性。

这可能是其他遇到 Python 文件路径问题的人的解决方案。


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