Переименуйте каталог с именем внутри, используя Python - PullRequest
3 голосов
/ 02 марта 2020

Я пытаюсь переименовать несколько каталогов с именем первого файла внутри них.

Я пытаюсь:

  1. Вывести список файлов в папке.
  2. Определите каталоги.
  3. Для каждого каталога, получить к нему доступ, взять имя первого файла внутри и переименовать каталог с таким именем.

Это то, что я получил до сих пор, но это не работает. Я знаю, что код неправильный, но перед исправлением кода я хотел бы узнать, верна ли логика c. Может кто-нибудь помочь, пожалуйста?

import os

for (root, dirs, files) in os.walk('.'):
    print(f'Found directory: {dirpath}')
    dirlist = []
    for d_idx, d in enumerate(dirlist):
        print(d)
    filelist = []
    for f_idex, f in enumerate(filelist):
        files.append(f)[1] 
        print(f)
    os.rename(d, f)

Спасибо!

1 Ответ

2 голосов
/ 02 марта 2020

В вашем коде есть несколько проблем:

  1. Вы переименовываете каталоги при их итерации с помощью os.walk. Это не очень хорошая идея, os.walk дает вам генератор, то есть он создает элементы во время их итерации, поэтому переименование вещей в l oop приведет их в замешательство.
  2. И for d_idx, d in enumerate(dirlist):, и for f_idex, f in enumerate(filelist): Перебирайте переменные, которые объявлены как пустые списки в строке ранее, поэтому эти циклы ничего не делают. Кроме того, во втором случае files.append(f) добавит f к списку files, но [1] в конце означает "получить второй элемент (запоминание Python индексирование основано на 0) значения возвращается функцией append "- но append ничего не возвращает (он изменяет список, не возвращает новый список), так что это может завершиться ошибкой (и вы все равно не используете значение, прочитанное [1], поэтому это ничего бы не сделало).
  3. Во-первых, os.rename(d, f), поскольку ранее циклы никогда не запускаются, d и f не будут иметь значения, но также при условии, что оба d и f получены из dirs и files, они будут заданы как пути относительно своих родителей, а не к вашему текущему каталогу (.), поэтому переименование будет неудачным.

Этот код должен работать так, как вы хотите:

import os

# List of paths to rename
renames = []
# Walk current dir
for (root, dirs, files) in os.walk('.'):
    # Skip this dir (cannot rename current directory)
    if root == '.': continue
    # Add renaming to list
    renames.append((root, files[0]))
# Iterate renaming list in reverse order so deepest dirs are renamed first
for root, new_name in reversed(renames):
    # Make new full dir name (relative to current directory)
    new_full_name = os.path.join(os.path.dirname(root), new_name)
    # Rename
    os.rename(root, new_full_name)
...