简体   繁体   中英

How to get the relative path between two absolute paths in Python using pathlib?

In Python 3, I defined two paths using pathlib , say:

from pathlib import Path

origin = Path('middle-earth/gondor/minas-tirith/castle').resolve()
destination = Path('middle-earth/gondor/osgiliath/tower').resolve()

How can I get the relative path that leads from origin to destination ? In this example, I'd like a function that returns ../../osgiliath/tower or something equivalent.

Ideally, I'd have a function relative_path that always satisfies

origin.joinpath(
    relative_path(origin, destination)
).resolve() == destination.resolve()

(well, ideally there would be an operator - such that destination == origin / (destination - origin) would always be true)

Note that Path.relative_to is not sufficient in this case, since origin is not a destination 's parent. Also, I'm not working with symlinks, so it's safe to assume that there are none if this simplifies the problem.

How can relative_path be implemented?

This is trivially os.path.relpath

import os.path
from pathlib import Path

origin      = Path('middle-earth/gondor/minas-tirith/castle').resolve()
destination = Path('middle-earth/gondor/osgiliath/tower').resolve()

assert os.path.relpath(destination, start=origin) == '..\\..\\osgiliath\\tower'

If you'd like your own Python function to convert an absolute path to a relative path:

def absolute_file_path_to_relative(start_file_path, destination_file_path):
    return (start_file_path.count("/") + start_file_path.count("\\") + 1) * (".." + ((start_file_path.find("/") > -1) and "/" or "\\")) + destination_file_path

This assumes that:

1) start_file_path starts with the same root folder as destination_file_path .

2) Types of slashes don't occur interchangably.

3) You're not using a filesystem that permits slashes in the file name.

Those assumptions may be an advantage or disadvantage, depending on your use case.

Disadvantages: if you're using pathlib, you'll break that module's API flow in your code by mixing in this function; limited use cases; inputs have to be sterile for the filesystem you're working with.

Advantages: runs 202x faster than @AdamSmith's answer (tested on Windows 7, 32-bit)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM