pathlib.Path.relative_to 与 os.path.relpath

lar*_*sks 19 python filesystems pathlib

我想找到两个绝对路径之间的相对路径。我有通常用于pathlib.Path与文件系统交互的现有代码,但我遇到了一个似乎很容易解决os.path.relpath但(到目前为止)很难解决的问题pathlib.Path

我有:

  • (A), 目录的绝对路径,/home/project/cluster-scope/base/namespaces/acm
  • (B),从(A) 到另一个目录的相对路径,../../../components/monitoring-rbac
  • (C)、第二个目录的绝对路径,/home/project/cluster-scope/base/core/namespaces/acm

我想计算从 (C) 到 (B) 的新相对路径。这有效:

>>> import os
>>> path_A = '/home/project/cluster-scope/base/namespaces/acm'
>>> path_B = '../../../components/monitoring-rbac'
>>> path_C = '/home/project/cluster-scope/base/core/namespaces/acm'
>>> path_B_abs = os.path.abspath(os.path.join(path_A, path_B))
>>> os.path.relpath(path_B_abs, path_C)
'../../../../components/monitoring-rbac'
Run Code Online (Sandbox Code Playgroud)

但这并不:

>>> from pathlib import Path
>>> path_A = Path('/home/project/cluster-scope/base/namespaces/acm')
>>> path_B = Path('../../../components/monitoring-rbac')
>>> path_C = Path('/home/project/cluster-scope/base/core/namespaces/acm')
>>> path_B_abs = (path_A / path_B).resolve()
>>> path_B_abs.relative_to(path_C)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.9/pathlib.py", line 928, in relative_to
    raise ValueError("{!r} is not in the subpath of {!r}"
ValueError: '/home/project/cluster-scope/components/monitoring-rbac' is not in the subpath of '/home/project/cluster-scope/base/core/namespaces/acm' OR one path is relative and the other is absolute.
Run Code Online (Sandbox Code Playgroud)

该异常中的消息ValueError似乎不准确,或者至少具有误导性:两条路径显然共享一个共同的父路径。有没有办法使用 来计算新的相对路径 pathlib.Path?我意识到我可以使用os.path.relpath它并完成它,但我很好奇我是否误解了 的方法的pathlib使用relative_to

Ret*_*i43 9

显然这是不可能的。根据一个问题

我同意改进错误消息(可能还有文档)是值得的。

从来没有明确表示relative_to只会看起来更深入(永远不会生成前导“..”部分) - 文档中最接近的提示是os.path.relpath是不同的(甚至在relative_to()中也没有)部分)。

在当前版本中,文档字符串

"""Return the relative path to another path identified by the passed
arguments.  If the operation is not possible (because this is not
a subpath of the other path), raise ValueError.
"""
Run Code Online (Sandbox Code Playgroud)