Python сохранение структуры каталогов при изменении файлов

Друзья, всем привет. Не могу разобраться с этим вопросом. Программа должна искать все *.dxf в заданном каталоге /Старые (и всех подкаталогах), вносить типовые изменения в чертеж, а затем сохранять в каталог /Новые с таким же именем и той же структурой пути.

from pathlib import Path
import glob
import ezdxf
from google.colab import drive
drive.mount('/content/drive', force_remount=True)

# Путь к старому каталогу
old_path = Path('/content/drive/My Drive/Старые')
# Путь к новому каталогу
new_path = Path('/content/drive/My Drive/Новые')

def save_new_dxf(file, doc):
    # Создаем новый путь для файла в новом каталоге
    new_file = new_path / file.name
    parent_dir = new_file.parent
    if not parent_dir.exists():
        parent_dir.mkdir(parents=True)
    doc.saveas(str(new_file))

def change_dxf(file):
    # Открываем чертеж
    doc = ezdxf.readfile(str(file))
    # Тут вносим типовые изменения

    # Передаём файл на сохранение
    save_new_dxf(file, doc)

# Перебираем все файлы в старом каталоге и подкаталогах с расширением .dxf
for file in old_path.glob('**/*.dxf'):
    change_dxf(file)

Всё отрабатывает классно, изменения есть, но файлы сохраняются в каталог /Новые без структуры, т.е. все файлы в одной папке.

Подозреваю ошибка в doc.saveas(str(new_file)) - как добавить в путь дочерние каталоги?


Ответы (1 шт):

Автор решения: mrgervant

Вы создаете путь к новому файлу через new_file = new_path / file.name Однако file.name это исключительно имя файла (предшествующие папки не входят). В результате new_file всегда формируется как сложение пути до новой папки и имени файла.

Для того, чтобы добавить названия подпапок из старой структуры, можно использовать функцию PurePath.relative_to. С данной функцией можно получить путь, начиная от имени файла до старой папки (не включая её, а также папки выше по структуре).

Создавая путь для нового файла как new_file = new_path / file.relative_to(old_path), мы будем складывать примерно следующее:

/content/drive/My Drive/Новые + test.dxf
/content/drive/My Drive/Новые + Подпапка1/test.dxf
/content/drive/My Drive/Новые + Подпапка1/Подподпапка1/test.dxf

Скорректированная функция:

def save_new_dxf(file, doc):
    # Создаем новый путь для файла в новом каталоге
    new_file = new_path / file.relative_to(old_path)
    parent_dir = new_file.parent
    if not parent_dir.exists():
        parent_dir.mkdir(parents=True)
    doc.saveas(str(new_file))
→ Ссылка