Python 3.6 pathlib Путь изменения имени родительского каталога

Новый пакет Path из библиотеки pathlib, который был добавлен из Python 3.4, кажется мощной заменой таких подходов, как os.path.join(), но у меня есть некоторые проблемы с работой с ним.

У меня есть путь, который может быть что угодно из folder_foo/file.csv в long/path/to/folder_foo/file.csv, Я читаю файл.csv в folder_foo с пандами, измените его и хотите сохранить в folder_bar/file.csv или же long/path/to/folder_bar/file.csv,

По сути хочу переименовать folder_foo в folder_bar в объекте Path.

РЕДАКТИРОВАТЬ: пример кода пути

csv_path = Path("long/path/to/folder_foo/file.csv")

попытки

1

csv_path.parents[0] = csv_path.parents[0] + "_clean")

Что приводит к ошибке TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str', что означает, что вы не можете использовать + объединить PosixPath с str как описано в TypeError: неподдерживаемые типы операндов для +: 'PosixPath' и 'str'.

2

Чтобы решить эту проблему, я попробовал следующее:

csv_path.parents[0] = Path(str(csv_path.parents[0]) + "_clean")

Что, однако, приводит к ошибке: TypeError: '_PathParents' object does not support item assignment,

поскольку PosixPath это не список, эта ошибка понятна.

3

Может быть .parts это лучший подход, но

csv_path.parts[-2] = csv_path.parts[-2][:-3] + "bar"

результаты в: TypeError: 'tuple' object does not support item assignment,

Вопрос

Как я могу легко переименовать родительскую папку файла?

3 ответа

Решение

РЕДАКТИРОВАТЬ: нашел более чистое решение без str()

csv_path2 = csv_path.parents[1] / (csv_path.parts[-2][:-3] + "bar") / csv_path.parts[-1]
# result
PosixPath('long/path/to/folder_bar/file.csv')

Path.parents получает полный путь к папке минус файл. Path.parents[1] поднимается на 2 уровня (long/path/to/), который по-прежнему является объектом Path. Затем мы получаем последнее имя папки с csv_path.parts[-2], который является строкой. Мы применяем [:-3] чтобы получить все строковые символы, кроме "foo", Это означает, что мы имеем "folder_", Затем с + "bar" мы получаем "folder_bar", который добавляется к нашему Path объект. Наконец, мы повторно добавляем имя файла в наш Path объект с / csv_path.parts[-1],

Взломать как решение

csv_path = Path(str(csv_path.parents[0])[:-3] + 'bar/' + csv_path.parts[-1])

Однако, мне кажется, что это немного не понятно. Должно быть более чистое решение?

Лучше бы разделить это для удобства чтения:

bar_folder = csv_path.parent.parent / 'folder_bar'
csv_path2 = bar_folder / csv_path.name

Наличие папки назначения в качестве переменной также позволяет вам создать папку, используя, например:

bar_folder.mkdir(exist_ok=True)

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

      from pathlib import Path

path1 = Path("a/b/c.txt")
path2 = Path("b/c.txt")

def rename_dir(path, src, dst):
    # convert to list so that we can change elements
    parts = list(path.parts)
    
    # replace part that matches src with dst
    parts[parts.index(src)] = dst
    
    return Path(*parts)

rename_dir(path1, 'b', 'q')
#> PosixPath('a/q/c.txt')

rename_dir(path2, 'b', 'q')
#> PosixPath('q/c.txt')

Создано 2021-03-06 10:44:00 PST, автор : rectxlite v0.4.2

Другие вопросы по тегам