Функція 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 для виконання складних операцій із файловою системою.
Favbet Tech – це ІТ-компанія зі 100% украінською ДНК, що створює досконалі сервіси для iGaming і Betting з використанням передових технологіи та надає доступ до них. Favbet Tech розробляє інноваційне програмне забезпечення через складну багатокомпонентну платформу, яка здатна витримувати величезні навантаження та створювати унікальний досвід для гравців.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: