Создать относительный путь с помощью шагов родительских каталогов - PullRequest
0 голосов
/ 17 сентября 2018

На всякий случай, если я что-то пропустил, и перед тем, как реализовать собственное решение проблемы.

В нашей системе сборки мне всегда приходится работать с относительными путями, чтобы все проекты были мобильными. Поэтому сценарии сборки должны генерировать относительные пути к файлам.

Все же кажется, что в библиотеке python нет функции, которая может обрабатывать шаги родительского пути, как показано в следующем примере:

from pathlib import Path
dir_a = Path("/home/example/solution/project")
file_b = Path("/home/example/solution/config.h")

Я бы хотел получить путь к file_b относительно dir_a. Поэтому, если я начну с dir_a, относительный путь будет указывать на file_b.

Лучший результат будет:

>>> file_b.relative_to(dir_a)
Path("../config.h")

Возьмите этот чуть более сложный пример:

from pathlib import Path
dir_a = Path("/home/example/solution/project_a")
file_b = Path("/home/example/solution/project_b/config.h")

Лучший результат будет:

>>> file_b.relative_to(dir_a)
Path("../project_b/config.h")

Оба примера, использующие методы .relative_to, не работают и вызывают исключение:

ValueError: '/home/example/solution/project_b/config.h' does not start with '/home/example/solution/project_a'

Метод os.path.relpath работает, как и ожидалось, но возвращает объект вместо Path объекта:

>>> os.path.relpath(file_b, dir_a)
'../project_b/config.h'

Так что мне интересно, если я что-то здесь упустил ...

Как получить относительный путь с родительскими каталогами, используя объекты Path?

Почему реализация relative_to объекта Path не работает?

1 Ответ

0 голосов
/ 17 сентября 2018

Некоторый путь х должен быть внутри некоторого базового пути. Вы получаете исключение ValueError, потому что project_b относится не к project_a, а к папке решения.

Например, чтобы лучше понять, вы должны иметь:

base = Path("/home/example/solution")
b_file = Path("/home/example/solution/project_b/config.h")
b_file.relative_to(base) # output >>> WindowsPath('project_b/config.h')

EDIT: Вы можете получить относительные каталоги в текущей папке с Path объектами, используя Path.glob() или Path.iterdir().

Вы узнаете, какой из них лучше подходит вашему делу.

По сути, вы можете сделать это:

base = Path('/home/example/solution') 
g = base.glob('/*') # grabs all files and dirs relative to the current folder as Path objects
try:
    while g:
        i = next(g)
        if i.match('project_b'):
            # if here is my folder then work with it
            b_file = i.joinpath('config.h')
        else:
            # work on a better look up maybe
            pass
except StopIteration:
    pass
...