Сообщить об ошибке.

Функция walk() модуля os в Python

Рекурсивное получение имен файлов в дереве каталогов

Синтаксис:

import os

os.walk(top, topdown=True, onerror=None, followlinks=False)

Параметры:

  • top - строка, вершинa каталога,
  • topdown=True - bool, направление обхода,
  • onerror=None - функция, которая сообщает об ошибке,
  • followlinks=False - bool, переходить ли по символическим ссылкам.

Возвращаемое значение:

Описание:

Функция walk() модуля os генерирует имена файлов в дереве каталогов, обходя дерево сверху вниз или снизу вверх. Для каждого каталога в дереве с корнем в вершине каталога top, включая саму вершину top, она выдает тройной кортеж (dirpath, dirnames, filenames).

  • dirpath - это строка, путь к каталогу.
  • dirnames - это список имен подкаталогов в dirpath, исключая особые символы '.' и '..'.
  • filenames - это список имен файлов в dirpath (не-каталогов).

Обратите внимание, что имена в списках не содержат компонентов пути. Чтобы получить полный путь, который начинается с top, к файлу или каталогу в dirpath, выполните os.path.join(dirpath, name).

Аргумент top может принимать объекты, представляющие путь к файловой системе, такие как pathlib.PurePath.

Если необязательный аргумент topdown имеет значение True или не указан, тройной кортеж для каталога создается перед тройным кортежем для любого из его подкаталогов, т. е. каталоги создаются сверху вниз. Если topdown имеет значение False, тройной кортеж для каталога создается после тройного кортежа для всех его подкаталогов, т. е. каталоги создаются снизу вверх. Независимо от значения topdown, список подкаталогов извлекается до создания кортежей для каталога и его подкаталогов.

Когда topdown имеет значение True, вызывающий объект может изменить список dirnames на месте, используя например del или slice и функция os.walk() будет возвращаться только в подкаталоги, чьи имена остаются в dirnames. Такое поведение может быть использовано для сокращения поиска, наложения определенного порядка посещения или даже для информирования os.walk() о каталогах, которые вызывающий абонент создает или переименовывает, прежде чем возобновится генерация имен файлов в дереве каталогов. Изменение dirnames, когда topdown имеет значение False не влияет на поведение обхода, поскольку в режиме снизу вверх каталоги с именами dirname генерируются до того, как генерируется сам dirpath.

По умолчанию ошибки из вызова os.scandir() игнорируются. Если указан необязательный аргумент onerror, это должна быть функция, которая будет вызвана с одним аргументом - экземпляром OSError. Функция может сообщить об ошибке, на основе которой можно будет принять решение о продолжении обхода дерева каталогов или прервать обход. Обратите внимание, что имя файла доступно как атрибут имени файла объекта исключения.

По умолчанию функция os.walk() не будет переходить по символическим ссылкам, которые ссылаются на каталоги. Установите для аргумента followlinks значение True, чтобы посещать каталоги, на которые указывают символические ссылки, в системах, которые их поддерживают.

Примечания:

  • Доступность: Unix.
  • Имейте в виду, что установка followlinks=True может привести к бесконечной рекурсии, если ссылка указывает на родительский каталог. Функция os.walk() не отслеживает уже посещенные каталоги.
  • Если вы передадите относительный путь, не меняйте текущий рабочий каталог между повторными выполнениями функции os.walk(). Функция os.walk() никогда не изменяет текущий каталог и предполагает, что его вызывающая сторона тоже не изменяет.

Дополнительно можно посмотреть:

  • os.listdir() - список файлов в директории/каталоге,
  • os.scandir() - информация о всех файлах/каталогах, включая его имя,
  • glob.glob() - рекурсивный поиск файлов по шаблону,
  • pathlib.Path.glob(pattern) - рекурсивный (в глубину) отбор файлов из каталога по шаблону.

Примеры практического применения функции os.walk().

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

import os
from os.path import join, getsize

for root, dirs, files in os.walk('python/Lib/email'):
    print(root, "consumes", end=" ")
    print(sum(getsize(join(root, name)) for name in files), end=" ")
    print("bytes in", len(files), "non-directory files")
    if 'CVS' in dirs:
        # не просматриваем каталог `CVS`
        dirs.remove('CVS')

В следующем примере простая реализация функции shutil.rmtree(). В функции os.walk() указан обход дерева каталогов снизу вверх, это очень важно, т. к. функция os.rmdir() не позволяет удалить каталог, пока он не пуст:

ВНИМАНИЕ! В примере удаляется все из каталога, указанного в переменной top, при условии, что нет символических ссылок. Это опасно! Например, если top == '/', это может удалить все файлы на диске.

import os

for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        os.rmdir(os.path.join(root, name))