加入时如何强制绝对路径是相对的?

How to force absolute path to be relative when joining?

加入时将绝对路径转换为相对路径的惯用方法是什么?

输入:

abs = r"\server\share\data"
newroot = r"X:\project"

想要的结果:

X:\project\server\share\data

os.path.join()pathlib.Path().joinpath() trim 盘符后的所有内容:

>>> os.path.join(newroot, abs)
'\\server\share\data'

>>> pathlib.Path(newroot).joinpath(abs)
WindowsPath('//server/share/data')

我可以通过去掉前导斜线来使它们工作:

>>> os.path.join(newroot, abs[2:])
'X:\project\server\share\data'

但这意味着我需要包含一个测试以查明传入路径是否实际上是绝对路径并计算要删除多少斜杠。这感觉就像是我制造错误的地方。

注意:显示了 Windows 语法,但我认为问题是跨平台的,最佳实践答案可能也是这样。

在找到可靠答案之前我一直在使用什么。它适用于我的情况,但我不指望它没有问题。

简洁:

def make_relative(path):
    '''Remove leading characters that make an absolute path'''
    while os.path.isabs(path):
        path = path[1:]
        if ':' in path[0]: path = path[1:]
    return path

信息:

def make_relative(path, debug=False):
    '''Remove leading characters that make an absolute path'''
    msg = [f"\nIn: {repr(path)}"]
    while os.path.isabs(path):
        msg.append(f'stripping {path[0]}')
        path = path[1:]
        if ':' in path[0]:
            msg.append(f'stripping {path[0]}')
            path = path[1:]
    msg.append(f'Out: {repr(path)}')
    if debug:
        [print(x) for x in msg]
    return path

if __name__ == '__main__':
    abs = r"\server\share\data"
    newroot = r"X:\project\test"

    make_relative(abs, debug=True)
    make_relative(newroot, debug=True)

结果:

In: '\\server\share\data'
stripping \
stripping \
Out: 'server\share\data'

In: 'X:\project\test'
stripping X
stripping :
stripping \
Out: 'project\test'