Standardní knihovna jazyka Python je vybavena rozsáhlou škálou nástrojů, které jsou klíčové pro řešení rozmanitých úkolů. V tomto článku se seznámíme s různými metodami, jak ověřit existenci souborů a složek, výhradně s využitím vestavěných modulů.
Kontrola, zda se soubor nebo skript nachází na správném místě, je zásadní pro spolehlivost libovolného programu, který se spouští z příkazové řádky. Pokud požadovaný soubor není k dispozici v okamžiku spuštění, program může být nefunkční.
V následujícím textu si projdeme několik rychlých způsobů, jak zjistit, zda v Pythonu existuje soubor nebo adresář.
Než začneme
Před pokračováním se ujistěte, že máte nainstalovaný Python verze 3. K ověření můžete použít terminál, kam zadáte následující příkaz:
python --version # Python 3.9.5, můj výsledek
Pokud máte nainstalovanou verzi 2.x, použijte příkaz „python3“. V případě, že nemáte nainstalovanou verzi Python 3, podívejte se do našeho návodu k instalaci.
V průběhu tohoto tutoriálu budeme pracovat s několika testovacími soubory. Vytvořte si prosím následující:
touch testfile.txt mkdir testdirectory/ touch testdirectory/otherfile.txt
Výše uvedené příkazy vygenerují soubor, který budeme používat pro testování, testovací adresář a další soubor v tomto adresáři. Soubory mohou být prázdné, protože nebudeme číst jejich obsah.
Poznámka: Uživatelé systému Windows mohou vytvořit tuto strukturu souborů pomocí grafického správce.
Pro interaktivní práci s Pythonem budeme používat Ipython, který nabízí uživatelsky přívětivé prostředí. Nicméně, není to nutné.
pip install ipython
Po dokončení instalace spustíte interaktivní prostředí Pythonu zadáním příkazu ipython.
Nyní jste připraveni prozkoumat metody, jak v Pythonu zjistit existenci složky nebo souboru.
Metoda Try, Open a Exception
Tato varianta je nejvíce přímočará. Pokud se pokusíte otevřít soubor, který neexistuje, Python vyvolá výjimku FileNotFoundError.
In [1]: open('im-not-here.txt') --------------------------------------------------------------------------- FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
Této skutečnosti můžeme využít a ošetřit výjimku, která nastane v případě, že soubor nenajdeme.
In [2]: try: ...: file = open('im-not-here.txt') ...: print(file) # File handler ...: file.close() ...: except FileNotFoundError: ...: print('Omlouvám se, hledaný soubor neexistuje') ...: exit() ...: Omlouvám se, hledaný soubor neexistuje
Výše uvedený kód vypíše na obrazovku vlastní zprávu a ukončí provádění programu, pokud soubor neexistuje.
Funkce exit() se provede pouze v případě, že je vyvolána výjimka. Nyní se podívejme, co se stane, když hledaný soubor existuje.
In [2]: try: ...: file = open('testfile.txt') ...: print(file) # File handler ...: file.close() ...: except FileNotFoundError: ...: print('Omlouvám se, hledaný soubor neexistuje') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Všimněte si, jak soubor zavíráme ihned po jeho otevření. To je považováno za správnou praxi dle dokumentace Pythonu.
Pokud voláme file.write() bez použití klíčového slova with nebo voláme file.close(), může se stát, že argumenty funkce file.write() nebudou kompletně zapsány na disk, i když program skončí bez chyb.
I když do souboru nezapisujeme, doporučuje se soubor zavřít, protože to může vést k problémům s výkonem.
Abychom nemuseli soubor zavírat sami, můžeme použít kontextový manažer with. Ten automaticky přiděluje a uvolňuje zdroje, takže se o zavření souboru nemusíme starat.
In [3]: try: ...: with open('testfile.txt') as file: ...: print(file) ...: # Není třeba soubor zavírat ...: except FileNotFoundError: ...: print('Omlouvám se, hledaný soubor neexistuje') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Tato metoda je velmi užitečná při zápisu do souborů, ale je neefektivní, pokud potřebujeme pouze zkontrolovat existenci souboru. Podívejme se na další možnosti.
os.path.exists()
Modul os poskytuje mnoho funkcí pro interakci s operačním systémem. Pro ověření, zda existuje soubor nebo adresář, můžeme použít funkci path.exists(), která jako argument přijímá cestu k souboru nebo adresáři. Funkce vrací booleovskou hodnotu v závislosti na existenci cesty.
Poznámka: Cesta je jedinečné umístění souboru nebo adresáře v souborovém systému.
V Pythonu je os.path submodul, který obsahuje funkce určené výhradně pro práci s cestami k souborům. Tyto funkce přijímají jako argument řetězce nebo bajty reprezentující cestu. Můžete použít absolutní cesty, jako například:
/home/daniel/.bashrc
Nebo relativní cesty v závislosti na adresáři, ve kterém skript spouštíte:
.bashrc # Spuštění skriptu v mém domovském adresáři
Zde je několik příkladů použití funkce os.path.exists() v adresáři, kde se nachází mé testovací soubory:
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
Jak vidíte, funkce vrací True, pokud testujeme soubor testfile.txt a složku testdirectory a False, pokud soubor neexistuje.
os.path.isfile()
Pokud chceme pouze ověřit existenci souboru (nikoli adresáře), můžeme použít funkci 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
Poznámka: V systémech UNIX adresáře končí lomítkem (/), zatímco v systémech Windows používáme zpětné lomítko (\).
V kódu výše funkce isfile() vrací False ve dvou případech. Podívejme se proč:
- testdirectory/ je adresář, proto se nepovažuje za soubor. To není zcela přesné, protože v Linuxu je vše deskriptorem souboru, ale Python s adresáři manipuluje odlišně pro naše pohodlí (při pokusu o otevření adresáře se zobrazí IsADirectoryError).
- i-dont-even-exist ukazuje na soubor, který paradoxně neexistuje.
os.path.isdir()
Pro ověření, zda daná cesta ukazuje na adresář, použijeme funkci os.path.isdir(), která vrací True pouze v případě, že daná cesta směřuje na adresář.
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
Všimněte si, že výše uvedené příklady vrátí hodnotu False i v případě, že cesta ukazuje na existující soubor.
Modul Glob
Modul glob poskytuje funkce pro práci s vzory podobnými shellu Unixu (proto nemusí fungovat správně v systémech Windows). Pro ověření, zda soubor odpovídá vzoru v aktuálním adresáři, můžeme použít funkci glob.glob().
In [1]: import glob In [2]: glob.glob('testfile.txt') Out[2]: ['testfile.txt'] In [3]: glob.glob('testdirectory') Out[3]: ['testdirectory']
V uvedeném kódu je vzor předávaný funkci glob běžný řetězec reprezentující cestu k testovacímu souboru a adresáři. Protože obě cesty existují, funkce vrací seznam s odpovídajícími cestami.
Poznámka: Pokud vzor neodpovídá, získáme prázdný seznam.
Vzhledem k tomu, že můžeme předat vzory funkci glob, podívejme se na některé z jejích hlavních výhod.
Níže uvedený kód získá všechny cesty k souborům s příponami .txt a .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']
Použití třídy Path
Třída Path je vynikajícím nástrojem pro práci s cestami, protože poskytuje přehledné rozhraní pro práci s cestami k souborům jako s objekty.
Další výhodou je, že instance třídy Path mají všechny potřebné metody pro získávání informací o dané cestě. To zahrnuje funkce podobné předchozím možnostem.
Poznámka: K použití knihovny pathlib potřebujete Python verze 3.4 nebo vyšší.
Metody třídy Path, které použijeme:
Ověření existence cesty
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
Funguje stejně jako os.path.exists().
Ověření, zda cesta ukazuje na soubor
In [5]: Path('testfile.txt').is_file() Out[5]: True In [6]: Path('testdirectory').is_file() Out[6]: False
Ekvivalent funkce os.path.isfile().
Ověření, zda cesta ukazuje na adresář
In [7]: Path('testfile.txt').is_dir() Out[7]: False In [8]: Path('testdirectory').is_dir() Out[8]: True
Odpovídá funkci os.path.isdir().
Modul subprocess
Pokud jste fanoušky modulu subprocess, měli byste vědět i o této možnosti. Můžete ověřit, zda soubor nebo složka existuje pomocí příkazu test.
Poznámka: Příkaz test funguje pouze v systému Unix.
Pro ověření existence se používají následující příznaky testovacího příkazu:
- test -e: Ověří, zda cesta existuje.
- test -f: Ověří, zda existuje soubor.
- test -d: Ověří, zda existuje složka.
Pokud se chcete dozvědět více, přečtěte si manuálovou stránku spuštěním příkazu:
man test
Ověření cesty pomocí modulu subprocess:
Následující kód ověří, zda cesta existuje porovnáním návratové hodnoty procesu s hodnotou 0.
Pamatujte, že v Linuxu, pokud proces proběhl úspěšně, vrátí hodnotu nula. Pokud ne, vrátí jinou hodnotu.
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
V prvním příkazu importujeme modul subprocess a poté pomocí funkce run získáme návratovou hodnotu.
Ověření existence souboru pomocí modulu subprocess
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0 Out[4]: True In [5]: run(['test', '-f', 'testdirectory']).returncode == 0 Out[5]: False
Ověření adresáře pomocí modulu subprocess:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0 Out[6]: False In [7]: run(['test', '-d', 'testdirectory']).returncode == 0 Out[7]: True
Tato možnost není příliš doporučovaná, protože spotřebovává více zdrojů a nezískáváme z ní žádné výhody.
Shrnutí
Python je oblíbený programovací jazyk pro automatizaci procesů v operačních systémech. Jednou z užitečných věcí, které s ním můžeme dělat, je ověřovat, zda existuje soubor nebo složka.
Nejjednodušší varianty:
- Otevírání souborů a zpracování výjimek.
- Použití funkce exists() z modulů os.path nebo pathlib.
V tomto článku jste se naučili:
- Jak otevřít soubor a zpracovat výjimku, pokud neexistuje.
- Význam cest.
- Tři různé funkce, které submodul os.path poskytuje pro ověření existence souboru nebo složky.
- Unix používá lomítka (/), zatímco Windows používá zpětná lomítka (\).
Další čtení: Co je podproces v Pythonu? [5 příkladů použití]