Стандартна бібліотека Python містить широкий набір інструментів, які можуть знадобитися розробнику для вирішення різноманітних задач. У цьому матеріалі ми розглянемо кілька методів, як за допомогою вбудованих модулів перевірити наявність файлу чи каталогу.
Переконання в тому, що потрібний файл або каталог знаходиться у відповідному місці, є ключовим аспектом для будь-якої програми, особливо тих, що працюють через командний рядок (CLI). Відсутність необхідного файлу під час виконання програми може зробити її непридатною до використання.
У цій статті ми детально розглянемо кілька швидких та ефективних способів перевірити існування файлу або папки в Python.
Перед початком роботи
Перед тим, як використовувати будь-який з описаних нижче методів, необхідно переконатися, що на вашому комп’ютері встановлено Python 3. Для цього відкрийте термінал і введіть команду:
python --version # Python 3.9.5, це мій результат
Якщо ви використовуєте версію 2.x, вам потрібно буде використовувати команду “python3”. Якщо у вас не встановлено Python 3, зверніться до нашого посібника з встановлення Python.
У цьому навчальному матеріалі ми будемо працювати з деякими тестовими файлами, тому створіть наступні файли та каталоги:
touch testfile.txt mkdir testdirectory/ touch testdirectory/otherfile.txt
Ці команди створять файл, тестовий каталог та інший файл всередині цього каталогу. Вміст файлів не має значення, оскільки ми не будемо їх читати.
Зверніть увагу: Якщо ви працюєте на Windows, створіть аналогічну структуру файлів через графічний файловий менеджер.
Нарешті, ми будемо використовувати Ipython як інтерактивну оболонку Python. Вона забезпечує зручний інтерфейс для роботи, але її використання не є обов’язковим.
pip install ipython
Після встановлення ви зможете запустити оболонку Python, просто ввівши “ipython”.
Тепер, коли все готово, давайте розглянемо різні способи перевірки наявності файлу або папки в Python.
Використання блоку try-except
Це, мабуть, найпростіший метод. Якщо ви спробуєте відкрити файл, якого не існує, Python згенерує помилку FileNotFoundError.
In [1]: open('im-not-here.txt') --------------------------------------------------------------------------- FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
Ми можемо використати цей факт, щоб обробити виняток, якщо файл, який ми шукаємо, відсутній.
In [2]: try: ...: file = open('im-not-here.txt') ...: print(file) # File handler ...: file.close() ...: except FileNotFoundError: ...: print('На жаль, файл, який ми шукаємо, не існує') ...: exit() ...: На жаль, файл, який ми шукаємо, не існує
У цьому коді ми виводимо спеціальне повідомлення і завершуємо програму, якщо файл не знайдено.
Функція `exit()` буде виконана тільки у разі виникнення винятку. Давайте подивимось, що станеться, якщо файл, який ми шукаємо, дійсно існує.
In [2]: try: ...: file = open('testfile.txt') ...: print(file) # File handler ...: file.close() ...: except FileNotFoundError: ...: print('На жаль, файл, який ми шукаємо, не існує') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Зверніть увагу, що ми закриваємо файл одразу після відкриття. Це вважається гарною практикою, згідно з документацією Python.
Виклик file.write() без використання ключового слова with або виклику file.close() може призвести до того, що дані не будуть повністю записані на диск, навіть якщо програма завершилася успішно.
Навіть якщо ми не записуємо дані у файл, рекомендується закривати його, щоб уникнути різних проблем з продуктивністю.
Щоб не закривати файл вручну, можна використовувати менеджер контексту `with`. Він гарантує правильне виділення та звільнення ресурсів, тому нам не потрібно буде викликати `close()`.
In [3]: try: ...: with open('testfile.txt') as file: ...: print(file) ...: # Не потрібно закривати файл ...: except FileNotFoundError: ...: print('На жаль, файл, який ми шукаємо, не існує') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Цей метод особливо корисний при записі у файли, але не є оптимальним, якщо нам потрібно лише перевірити наявність файлу. Давайте розглянемо інші способи досягнення цієї мети.
Використання os.path.exists()
Модуль `os` надає різноманітні функції для взаємодії з операційною системою. Для перевірки наявності файлу або папки можна скористатися функцією `path.exists()`, яка приймає шлях до файлу або каталогу як аргумент. Вона повертає логічне значення (True або False) залежно від існування шляху.
Зауваження: Шлях – це унікальне розташування файлу або каталогу у файловій системі.
У Python підмодуль `os.path` містить функції, призначені спеціально для роботи зі шляхами до файлів. Усі ці функції приймають шлях як рядок або байти. Ви можете працювати як з абсолютними шляхами, наприклад:
/home/daniel/.bashrc
так і з відносними шляхами, наприклад, відносно поточного каталогу:
.bashrc # Скрипт виконується з домашнього каталогу
Ось кілька прикладів використання `os.path.exists()`, виконаних у каталозі, де знаходяться наші тестові файли:
In [1]: import os In [2]: os.path.exists('testfile.txt') Out[2]: True In [3]: os.path.exists('testdirectory') Out[3]: True In [4]: os.path.exists('hey-i-dont-exist') Out[4]: False
Як бачите, функція повертає True, коли тестується з файлом `testfile.txt` і папкою `testdirectory`, та False, якщо файл не існує.
Використання os.path.isfile()
Якщо вам потрібно підтвердити тільки існування файлу (а не каталогу), потрібно використовувати функцію `os.path.isfile()`.
In [1]: import os In [2]: os.path.isfile('testfile.txt') Out[2]: True In [3]: os.path.isfile('testdirectory/') Out[3]: False In [4]: os.path.isfile('i-dont-even-exist') Out[4]: False In [5]: os.path.isfile('testdirectory/otherfile.txt') Out[5]: True
Зауваження: У UNIX усі каталоги закінчуються косою рискою (/), тоді як у Windows використовується зворотна коса риска (\).
У наведеному вище прикладі функція `isfile()` повертає False у двох випадках, давайте розглянемо чому:
- `testdirectory/` є каталогом, тому не вважається файлом. Хоча в Linux все є файловим дескриптором, Python для зручності обробляє каталоги окремо. (Якщо ви спробуєте відкрити каталог, ви отримаєте помилку `IsADirectoryError`).
- `i-dont-even-exist` вказує на файл, якого не існує.
Використання os.path.isdir()
Якщо ви хочете перевірити, чи каталог знаходиться у потрібному місці, потрібно використовувати функцію `os.path.isdir()`, яка повертає True, тільки якщо вказаний шлях веде до каталогу.
In [1]: import os In [2]: os.path.isdir('testfile.txt') Out[2]: False In [3]: os.path.isdir('testdirectory') Out[3]: True In [4]: os.path.isdir('anotherfile.txt') Out[4]: False
Зверніть увагу, що наведені вище приклади повертають False, навіть якщо шлях вказує на існуючий файл.
Використання glob
Модуль `glob` надає інструменти для роботи з шаблонами, схожими на шаблони командної оболонки Unix (тому він може працювати некоректно в Windows). Щоб перевірити, чи файл відповідає шаблону в поточному каталозі, можна використовувати функцію `glob.glob()`.
In [1]: import glob In [2]: glob.glob('testfile.txt') Out[2]: ['testfile.txt'] In [3]: glob.glob('testdirectory') Out[3]: ['testdirectory']
У цьому коді шаблон, що передається в `glob`, – це звичайний рядок, який представляє шлях до тестового файлу та каталогу. Оскільки обидва шляхи існують, функція повертає список з відповідними іменами шляхів.
Зауваження: Якщо шаблон не збігається, ви отримаєте порожній список.
Враховуючи, що ми можемо передавати шаблони до функції `glob`, давайте розглянемо її можливості:
Наведений нижче код отримує всі шляхи до файлів з розширенням `.txt` і `.py` відповідно:
In [4]: glob.glob('*.txt') Out[4]: ['testfile.txt'] In [5]: glob.glob('*.py') Out[5]: ['pathlib-exists.py', 'list-dir.py', 'glob-file.py', 'open-except.py', 'subprocess-test.py', 'isfile.py', 'exists.py', 'isdir.py']
Використання класу Path
Клас `Path` – це зручний спосіб роботи зі шляхами, оскільки він надає зрозумілий інтерфейс для роботи з файловими шляхами як з об’єктами.
Екземпляри класу Path мають методи, необхідні для отримання інформації про певний шлях, включаючи функції, аналогічні розглянутим вище.
Зауваження: Щоб використовувати бібліотеку `pathlib`, вам потрібен Python 3.4 або новішої версії.
Методи `Path`, які ми будемо використовувати:
Перевірка існування шляху
In [1]: from pathlib import Path In [2]: Path('testfile.txt').exists() Out[2]: True In [3]: Path('im-not-here.txt').exists() Out[3]: False In [4]: Path('testdirectory').exists() Out[4]: True
Працює так само, як `os.path.exists()`.
Перевірка, чи шлях вказує на файл
In [5]: Path('testfile.txt').is_file() Out[5]: True In [6]: Path('testdirectory').is_file() Out[6]: False
Еквівалентно `os.path.isfile()`.
Перевірка, чи шлях вказує на каталог
In [7]: Path('testfile.txt').is_dir() Out[7]: False In [8]: Path('testdirectory').is_dir() Out[8]: True
Відповідає `os.path.isdir()`.
Використання підпроцесу
Якщо ви знайомі з модулем підпроцесів, вам потрібно знати про цю можливість. Ви можете визначити, чи існує файл або папка, використовуючи команду `test`.
Зауваження: Команда `test` працює тільки в Unix-подібних системах.
Наступні параметри команди `test` виконають необхідну роботу:
- `test -e`: перевіряє, чи існує шлях
- `test -f`: перевіряє, чи існує файл
- `test -d`: перевіряє, чи існує папка
Щоб дізнатися більше про команду `test`, можна прочитати посібник, виконавши:
man test
Перевірка шляху з використанням підпроцесу:
Наведений нижче код визначає, чи існує шлях, порівнюючи код повернення підпроцесу з 0.
Пам’ятайте, що в Linux, якщо процес виконався успішно, він поверне нуль, якщо ні, він поверне будь-який інший код.
In [1]: from subprocess import run In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0 Out[2]: True In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0 Out[3]: False
У першому рядку ми імпортуємо модуль підпроцесів, а потім використовуємо функцію `run` і отримуємо її код повернення.
Перевірка існування файлу з підпроцесом
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0 Out[4]: True In [5]: run(['test', '-f', 'testdirectory']).returncode == 0 Out[5]: False
Перевірка каталогу з підпроцесом:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0 Out[6]: False In [7]: run(['test', '-d', 'testdirectory']).returncode == 0 Out[7]: True
Використання цього методу не є рекомендованим, оскільки він споживає більше ресурсів і не дає особливих переваг.
Підсумок
Python є однією з найпопулярніших мов програмування для автоматизації процесів шляхом взаємодії з операційною системою. Однією з важливих задач, які можна вирішити за допомогою Python, є перевірка існування файлів або папок.
Найпростіші способи це зробити:
- Відкриття файлу та обробка винятків.
- Використання функції `exists()` з модулів `os.path` або `pathlib`.
У цьому матеріалі ви дізналися:
- Як відкрити файл і обробити виняток, якщо його не існує.
- Що таке шлях до файлу.
- Підмодуль `os.path` надає 3 різні функції для перевірки існування файлу або папки.
- В Unix використовуються косі риски (/), а в Windows зворотні косі риски (\).
Далі читайте: Що таке підпроцес у Python? [5 прикладів використання]