Рубріки: ОсновиТеорія

Функція 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 для виконання складних операцій із файловою системою.

Останні статті

Більше 8 млрд грн податків. Стільки сплатили резиденти Дія.City в І кварталі 2025 року

Резиденти Дія.City сплатили до бюджету понад 8 млрд грн податків в І кварталі 2025 року.…

18.04.2025

Китайських офісних працівників закликають менше працювати. Це має допомогти місцевій економіці

У Китаї закликають офісних працівників не працювати надто багато — держава сподівається, що вільний час…

18.04.2025

ChatGPT значно покращив пошук місць по фото. Це посилює проблеми конфіденційності

Експерти звертають увагу на тривожну тенденцію: люди все частіше використовують ChatGPT, щоб визначити місцезнаходження, зображене…

18.04.2025

Середовище розробки IntelliJ IDEA оновлено до версії 2025.1

Компанія JetBrains випустила нову версію мультимовного середовища розробки IntelliJ IDEA 2025.1. Оновлена IDE отримала численні…

18.04.2025

Discord впроваджує функцію сканування обличчя для перевірки віку користувачів

Платформа обміну миттєвими повідомленнями Discord впроваджує функцію перевірки віку за допомогою сканування обличчя. Зараз вона…

18.04.2025

Wikipedia випустила спеціальний датасет, щоб відволікти увагу ботів

Wikipedia намагається захистити себе від тисяч різноманітних ботів-скрейперів, які сканують дані цієї платформи для навчання…

18.04.2025