Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pathlib';对于同一级别上的目录,s相对\u_Python_Pathlib - Fatal编程技术网

Python 使用pathlib';对于同一级别上的目录,s相对\u

Python 使用pathlib';对于同一级别上的目录,s相对\u,python,pathlib,Python,Pathlib,python库提供了。如果一条路径是另一条路径的子路径,则此函数可以正常工作,如下所示: from pathlib import Path foo = Path("C:\\foo") bar = Path("C:\\foo\\bar") bar.relative_to(foo) > WindowsPath('bar') 但是,如果两条路径位于同一级别上,relative\u to不起作用 baz = Path("C:\\baz") foo.relative_to(baz) >

python库提供了。如果一条路径是另一条路径的子路径,则此函数可以正常工作,如下所示:

from pathlib import Path
foo = Path("C:\\foo")
bar = Path("C:\\foo\\bar")
bar.relative_to(foo)

> WindowsPath('bar')
但是,如果两条路径位于同一级别上,
relative\u to
不起作用

baz = Path("C:\\baz")
foo.relative_to(baz)

> ValueError: 'C:\\foo' does not start with 'C:\\baz'
我希望结果是

WindowsPath("..\\baz")
该函数可正确执行此操作:

import os
foo = "C:\\foo"
bar = "C:\\bar"
os.path.relpath(foo, bar)

> '..\\foo'

有没有一种方法可以使用
pathlib.path
实现
os.path.relpath
的功能?

第一部分解决了OP的问题,但如果像我一样,他真的想要相对于公共根的解决方案,那么第二部分为他解决了这个问题。第三部分描述了我最初是如何处理它的,并且出于兴趣而保留了它

相对路径 最近,正如在Python3.4-6中一样,
os.path
模块被扩展为接受
pathlib.path
对象。但是,在以下情况下,它不会返回路径对象,并且会强制包装结果

foo = Path("C:\\foo")
baz = Path("C:\\baz")
Path(os.path.relpath(foo, baz))

> Path("..\\foo")
公共路径 我怀疑你真的在寻找一条相对于公共根的路径。如果是这样的话,下面的,从,是更有用的

Path(os.path.commonpath([foo, baz]))

> Path('c:/root')
公共前缀 在我想到
os.path.commonpath
之前,我使用了
os.path.comonprefix

foo = Path("C:\\foo")
baz = Path("C:\\baz")
baz.relative_to(os.path.commonprefix([baz,foo]))

> Path('baz')
但是要预先警告,您不应该在这种情况下使用它(请参阅)

而是下面的一个

。。。或者如果你觉得冗长

from itertools import takewhile
Path(*[set(i).pop() for i in (takewhile(lambda x : x[0]==x[1], zip(foo.parts, baz.parts)))])

这一直困扰着我,所以这里有一个pathlib版本,我认为它和os.path.relpath一样

def relpath(path_to, path_from):
    path_to = Path(path_to).resolve()
    path_from = Path(path_from).resolve()
    try:
        for p in (*reversed(path_from.parents), path_from):
            head, tail = p, path_to.relative_to(p)
    except ValueError:  # Stop when the paths diverge.
        pass
    return Path('../' * (len(path_from.parents) - len(head.parents))).joinpath(tail)

你解决过这个问题吗?我遇到了同样的问题。我希望尽可能在os.path上使用pathlib进行标准化,但这个问题一直困扰着我。@Phil在这种情况下,您似乎不得不回到
os.path.relpath
:(…似乎
pathlib
模块没有被认为是
os.path
的替代品:(.或者您是否找到了仅限
pathlib
的解决方案?不,我没有找到仅限
pathlib
的解决方案。您应该接受@Carel的答案作为StackOverflow的最佳答案之一!谢谢:)只是吹毛求疵,如果任何路径是符号链接,这将导致不同的结果。
from itertools import takewhile
Path(*[set(i).pop() for i in (takewhile(lambda x : x[0]==x[1], zip(foo.parts, baz.parts)))])
def relpath(path_to, path_from):
    path_to = Path(path_to).resolve()
    path_from = Path(path_from).resolve()
    try:
        for p in (*reversed(path_from.parents), path_from):
            head, tail = p, path_to.relative_to(p)
    except ValueError:  # Stop when the paths diverge.
        pass
    return Path('../' * (len(path_from.parents) - len(head.parents))).joinpath(tail)