Функція walk() модуля OS у Python
Сьогодні поговоримо про такий важливий інструмент для роботи з файловою системою, як функція walk(), яка дозволяє отримувати відомості про дані (файли та каталоги) та вносити в них зміни.
Призначення функції os.walk()
Модуль OS у Python часто використовується для взаємодії з функціями операційної системи, зокрема — для керування файлами та каталогами. Щоб виконати навігацію по файловій системі, потрібно застосувати одну з функцій цього модуля — os.walk().

Фрагмент коду нижче знаходить усі папки та файли у зазначеній директорії та виводить їх повний шлях на екран. Ось як він працює:
- функція
os.walk()проходить по всіх файлах та папках у зазначеній директорії та надає три значення: (1) поточна папка, (2) список підпапок та (3) список файлів ; - потім використовується
os.path.join()для отримання повного шляху до файлу або папки.
Після цього шлях виводиться на екран:
import os
def main():
directory = "highload_today_directory"
for root, dirs, files in os.walk(directory):
print("Початковий каталог:", root)
print("Вкладені папки:")
for dir_name in dirs:
print(os.path.join(root, dir_name))
print("Файли:")
for file_name in files:
print(os.path.join(root, file_name))
print()
if __name__ == "__main__":
main()
Аргументи функції os.walk()
У переважній більшості випадків для функції os.walk() достатньо використовувати аргумент top — шлях до директорії, з якою потрібно виконувати обхід файлової системи.
Синтаксис функції передбачає також три необов’язкові аргументи:
- Так, якщо передати функції
os.walk()аргументtopdownз логічним значеннямFalse, перебір виконується від вкладених каталогів до зовнішніх. Відповідно, якщо цей параметр набуває значенняTrue(за замовчуванням), обхід йде від верхнього рівня до внутрішніх директорій. - Інший необов’язковий аргумент —
onerror, Функція-обробник помилок (за замовчуваннямNone). - І останній необов’язковий аргумент —
followlinks(за замовчуваннямFalse). Це логічне значення, яке вказує на те, чи потрібно слідувати символічним посиланням. При значенніfollowlinks=Falseсимволічні посилання ігноруються, а обхід обмежений лише структурою директорій.
Переваги os.walk()
За рахунок особливостей своєї роботи функція os.walk()може заощадити вам ресурси. У процесі звернення до os.walk(), виконується обхід файлової системи із зазначеного стартового шляху. Під час обходу, os.walk() генерує кортежі з інформацією про поточний каталог, вкладені каталоги, а також файли.
При цьому функція os.walk() не повертає всі значення відразу, а натомість повертає особливий тип об’єкта — об’єкт-генератор. Він генерує значення при необхідності, запам’ятовуючи поточний стан.
Тобто, якщо у вас є цикл for, ви можете зупинити обхід директорій, якщо в цьому є необхідність, а потім продовжити з цього моменту.
Наприклад, це може виглядати так:
import os start_path = '/якийсь/довгий/шлях/до/директорії' generator = os.walk(start_path) # Перебираємо перші 206 файлів for root, dirs, files in generator: for file in files: # Обробка файла print(os.path.join(root, file)) # Вимикаємо обхід після 206 файлів if len(files) > 206: break else: continue break # Знову запускаємо обхід з того етапу, на якому зупинились for root, dirs, files in generator: for file in files: # Обробка файла print(os.path.join(root, file))
Коли ми використовуємо об’єкт-генератор у циклі for, він автоматично отримує нові значення з os.walk() кожної ітерації. Це означає, що інформація про директорії та файли генерується в міру обходу файлової системи, а не завантажується одразу.
У випадках, коли йде обробка великого масиву даних, скажімо, мільйона файлів, такий підхід заощаджує пристойний обсяг пам’яті, необхідний зберігання цих значень.
Зверніть увагу на синтаксис у адресі шляху — для різних ОС він буде свій. Шлях, вказаний на Linux і macOS буде містити прямий слеш (/), в той час як шлях на Windows виглядатиме так:
start_path = 'C:\\Users\\Username\\Documents'
Або з префіксом на вказівку сирого (raw) рядка, для якого зворотний слеш не екранується:
start_path = r'C:\Users\Username\Documents'
Приклади використання функції os.walk()
Знаходження дублікатів
Стандартна бібліотека Python містить модуль hashlib, який можна задіяти в парі з функцією os.walk() для пошуку в директоріях файлів-дублікатів. У цьому випадку програма порівнюватиме їх хеш-суми та робитиме висновок про ідентичність даних:
import os
import hashlib
def get_file_hash(file_path):
"""Визначає хеш файла"""
with open(file_path, 'rb') as f:
data = f.read()
file_hash = hashlib.sha256(data).hexdigest()
return file_hash
def find_duplicate_files(start_path):
"""Виявляє ідентичні файли у вказанному каталозі, а також у всіх вкладених каталогах"""
file_hashes = {} # Словник для хешей файлів
duplicate_files = [] # Список для збереження дубликатів файлов
for root, dirs, files in os.walk(start_path):
for file_name in files:
file_path = os.path.join(root, file_name)
file_hash = get_file_hash(file_path)
if file_hash in file_hashes:
duplicate_files.append((file_path, file_hashes[file_hash]))
else:
file_hashes[file_hash] = file_path
return duplicate_files
start_path = '/path/to/directory'
duplicates = find_duplicate_files(start_path)
if duplicates:
print("Знайдені дубликати:")
for file1, file2 in duplicates:
print(file1, "та", file2)
else:
print("Файлів з ідентичним змістом не знайдено")
У коді вище йде звернення до функції get_file_hash(), щоб обчислити хеш кожного файлу за алгоритмом SHA-256. Після цього хеш та шлях до файлу зберігаються у словнику file_hashes. Якщо буде знайдено файл з аналогічним хешем, він додасться до списку duplicate_files.
Пакетне перейменування
Припустимо, потрібно перейменувати групу файлів у директоріїC:\foto, додавши до кожного префікс Highloadtoday_. У цьому випадку ми можемо використовувати код:
import os start_dir = start_path = 'C:\\foto' add_prefix = 'Highloadtoday_' for root, dirs, files in os.walk(start_dir): for file in files: file_path = os.path.join(root, file) edit_file_name = add_prefix + file edit_file_path = os.path.join(root, edit_file_name) os.rename(file_path, edit_file_path) print(file_path, edit_file_name)
Зверніть увагу! Змінна edit_file_name в коді лишається сталою протягом виконання скрипту.
Навіть якщо у файловому менеджері вручну повернути ім’я файлу до початкового стану, змінна edit_file_name залишається з префіксом Highloadtoday_.
Тому в консолі Python буде помилково писати в назві файлу Highloadtoday_Highloadtoday_Highloadtoday_....., додавая префікс щоразу на початок назви файлу при кожному наступному виконанні скрипта (навіть якщо ми перейменували файл).
Аби позбавитись цього незначного бага, просто використовуйте іншу функцію модуля — os.path.basename(). Вона дозволить зчитати им’я файла без посилання і добавить префікс коректно:
import os start_dir = 'C:\\foto' add_prefix = 'Highloadtoday_' for root, dirs, files in os.walk(start_dir): for file in files: if not file.startswith(add_prefix): file_path = os.path.join(root, file) file_name = os.path.basename(file_path) # отримаємо ім'я файла без його адреси edit_file_name = add_prefix + file_name # Додаємо префикс до імені файла edit_file_path = os.path.join(root, edit_file_name) os.rename(file_path, edit_file_path) print(file_path, edit_file_name)
Висновок
Тепер ви знаєте, як у Python легко та просто обходити директорії, отримуючи інформацію про каталоги та файли вашої файлової системи. Функція os.walk() ефективна при работі з великим об’ємом данних, а також легко комбинується з іншими стандартними командами Python для виконання складних операцій із файловою системою.












Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: