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.