Python standardna biblioteka obuhvata većinu funkcionalnosti koje su programeru neophodne za rešavanje problema. U ovom vodiču istražićemo različite metode za proveru da li datoteka ili direktorijum postoje, koristeći isključivo ugrađene module.
Provera ispravne lokacije datoteke ili skripte je od vitalnog značaja za svaki CLI program. Vaš program može postati nefunkcionalan ukoliko određena datoteka nije prisutna u trenutku izvršenja.
U današnjem vodiču, upoznaćemo se sa nekoliko brzih načina za proveru postojanja datoteke ili fascikle u Python-u.
Priprema za početak
Pre nego što primenite bilo koju od narednih komandi, uverite se da je Python 3 instaliran na vašem sistemu. Otvorite svoj terminal i unesite sledeću komandu:
python --version # Python 3.9.5, rezultat
Ukoliko imate verziju 2.x, moraćete da koristite komandu „python3“. Proverite naš vodič za instalaciju Python-a ako nemate instaliran Python 3.
Koristićemo test datoteke tokom ovog vodiča, stoga kreirajte sledeće datoteke:
touch testfile.txt mkdir testdirectory/ touch testdirectory/otherfile.txt
Gornje komande kreiraju test datoteku, test direktorijum i drugu datoteku unutar test direktorijuma. Ove datoteke mogu biti prazne, jer njihov sadržaj neće biti od značaja.
Napomena: Ako koristite Windows, napravite sličnu strukturu datoteka pomoću grafičkog upravljača datotekama.
Takođe, koristićemo IPython kao interaktivni Python shell koji nudi praktičan interfejs za rad. Ovo je opciono i nije neophodno.
pip install ipython
Nakon toga, imaćete pristup Python shell-u unosom komande `ipython`.
Sada ste spremni, možemo početi sa istraživanjem različitih metoda za proveru postojanja fascikle ili datoteke u Python-u.
Try, Open i Except
Ovo je najdirektniji pristup. Ukoliko pokušate da otvorite datoteku koja ne postoji, Python će generisati FileNotFoundError.
In [1]: open('im-not-here.txt') --------------------------------------------------------------------------- FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
Ovu grešku možemo iskoristiti i rukovati njome ukoliko datoteka ne postoji.
In [2]: try: ...: file = open('im-not-here.txt') ...: print(file) # Rukovalac datotekom ...: file.close() ...: except FileNotFoundError: ...: print('Datoteka koju tražimo ne postoji') ...: exit() ...: Datoteka koju tražimo ne postoji
U prikazanom kodu, ispisujemo poruku prilagođenu korisniku i zaustavljamo izvršavanje programa ukoliko datoteka nije pronađena.
Obratite pažnju na to kako se funkcija `exit()` izvršava samo ako se pojavi greška. Pogledajmo šta se dešava kada datoteka koju tražimo zaista postoji.
In [2]: try: ...: file = open('testfile.txt') ...: print(file) # Rukovalac datotekom ...: file.close() ...: except FileNotFoundError: ...: print('Datoteka koju tražimo ne postoji') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Važno je napomenuti da datoteku zatvaramo odmah nakon otvaranja, što je preporučeno prema Python dokumentaciji.
Pozivanje file.write() bez korišćenja ključne reči with ili pozivanja file.close() može dovesti do toga da argumenti file.write() ne budu u potpunosti upisani na disk, čak i ako se program uspešno završi.
Čak i ako ne vršimo upisivanje u datoteku, preporučljivo je da je zatvorimo, jer to može dovesti do problema sa performansama.
Ako ne želimo sami da zatvaramo datoteku, možemo koristiti menadžer konteksta `with`. On obezbeđuje automatsko dodeljivanje i oslobađanje resursa, te datoteku nećemo morati zatvarati ručno.
In [3]: try: ...: with open('testfile.txt') as file: ...: print(file) ...: # Nema potrebe za zatvaranjem datoteke ...: except FileNotFoundError: ...: print('Datoteka koju tražimo ne postoji') ...: exit() ...: ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Ova metoda je posebno korisna kada se upisuje u datoteke, ali nije najefikasnija ako želimo samo da proverimo postojanje datoteke. Istražimo druge opcije za to.
os.path.exists()
`os` modul nudi brojne funkcije za interakciju sa operativnim sistemom. Za proveru da li datoteka ili fascikla postoji, možemo koristiti funkciju `path.exists()` koja prihvata putanju do datoteke ili direktorijuma kao argument. Funkcija vraća logičku vrednost na osnovu postojanja zadate putanje.
Napomena: Putanja predstavlja jedinstvenu lokaciju datoteke ili direktorijuma u sistemu datoteka.
U Python-u, `os.path` podmodul sadrži funkcije koje su specijalizovane za rad sa putanjama datoteka. Ove funkcije prihvataju argument putanje kao stringove ili bajtove, a možete raditi sa apsolutnim putanjama, na primer:
/home/daniel/.bashrc
Ili sa relativnim putanjama, u zavisnosti od direktorijuma u kom se skripta pokreće:
.bashrc # Pokretanje skripte iz kućnog direktorijuma
Evo još primera korišćenja `os.path.exists()` funkcije, pokrenute u direktorijumu gde se nalaze moje test datoteke:
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
Kao što vidite, funkcija vraća `True` kada se testira sa `testfile.txt` datotekom i `testdirectory` direktorijumom, a `False` kada datoteka ne postoji.
os.path.isfile()
Ako želite da potvrdite postojanje samo datoteke (ne direktorijuma), koristite funkciju `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
Napomena: U UNIX sistemima, svi direktorijumi se završavaju sa kosom crtom ( `/` ), dok se u Windowsu koristi obrnuta kosa crta ( `\` ).
U navedenom kodu, `isfile()` funkcija vraća `False` u dva slučaja, razmotrimo zašto:
- `testdirectory/` je direktorijum, stoga se ne smatra datotekom. Ovo nije potpuno tačno, jer u Linux-u sve je deskriptor datoteke, ali Python tretira direktorijume drugačije radi praktičnosti (ako pokušate da otvorite direktorijum, dobićete `IsADirectoryError`)
- `i-dont-even-exist` ukazuje na datoteku koja ne postoji.
os.path.isdir()
Ako želite da proverite da li je direktorijum na ispravnoj lokaciji, potrebno je da koristite funkciju `os.path.isdir()`, koja vraća `True` samo ako data putanja ukazuje na direktorijum.
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
Obratite pažnju da gornji primeri vraćaju `False` čak i kada putanja ukazuje na datoteku koja postoji.
Glob
`glob` modul nudi funkcije za rad sa Unix obrascima sličnim shell-u (stoga ne funkcioniše ispravno na Windows-u). Da biste proverili da li datoteka odgovara obrascu unutar trenutnog direktorijuma, možete koristiti `glob.glob()` funkciju.
In [1]: import glob In [2]: glob.glob('testfile.txt') Out[2]: ['testfile.txt'] In [3]: glob.glob('testdirectory') Out[3]: ['testdirectory']
U gornjem kodu, obrazac prosleđen `glob` funkciji je običan string koji predstavlja putanju do test datoteke i direktorijuma. Pošto obe putanje postoje, funkcija vraća listu sa odgovarajućim imenima putanja.
Napomena: Ako se obrazac ne poklapa, dobićete praznu listu.
S obzirom na to da možemo proslediti obrasce u `glob` funkciju, hajde da iskoristimo neke od njenih prednosti.
Sledeći kod dobija sve putanje datoteka sa ekstenzijama `.txt` i `.py` respektivno:
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']
Korišćenje klase Path
Klasa Path predstavlja jedan od najboljih načina za rad sa putanjama, jer pruža čist interfejs za tretiranje putanja kao objekata.
Ključno je to što instance `Path` klase imaju sve metode potrebne za dobijanje informacija o određenoj putanji. Ovo uključuje funkcionalnosti slične prethodnim opcijama.
Napomena: Za korišćenje `pathlib` biblioteke neophodan je Python 3.4 ili noviji.
Metode `Path` klase koje ćemo koristiti:
Provera postojanja putanje
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
Radi isto kao `os.path.exists()`.
Provera da li putanja ukazuje na datoteku
In [5]: Path('testfile.txt').is_file() Out[5]: True In [6]: Path('testdirectory').is_file() Out[6]: False
Ekvivalentno `os.path.isfile()`.
Provera da li putanja ukazuje na direktorijum
In [7]: Path('testfile.txt').is_dir() Out[7]: False In [8]: Path('testdirectory').is_dir() Out[8]: True
Odgovara `os.path.isdir()`.
subprocess
Ako ste ljubitelj `subprocess` modula, ova opcija će vam biti korisna. Možete utvrditi da li datoteka ili fascikla postoji korišćenjem `test` komande.
Napomena: `test` komanda radi samo u Unix-like okruženjima.
Sledeće `test` zastavice će obaviti posao:
- `test -e`: Proverava da li putanja postoji.
- `test -f`: Proverava da li datoteka postoji.
- `test -d`: Proverava da li direktorijum postoji.
Ukoliko želite da saznate više o `test` zastavicama, možete pročitati uputstvo pokretanjem komande:
man test
Provera putanje pomoću subprocess modula:
Sledeći kod određuje da li putanja postoji poređenjem povratne vrednosti potprocesa sa 0.
U Linux-u, ako proces prođe uspešno, vratiće nulu, a u suprotnom, bilo koji drugi kod.
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
U prvom koraku uvozimo `subprocess` modul, a zatim koristimo `run` funkciju i dobijamo povratnu vrednost.
Provera postojanja datoteke pomoću subprocess modula
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0 Out[4]: True In [5]: run(['test', '-f', 'testdirectory']).returncode == 0 Out[5]: False
Provera direktorijuma pomoću subprocess modula:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0 Out[6]: False In [7]: run(['test', '-d', 'testdirectory']).returncode == 0 Out[7]: True
Nije preporučljivo koristiti ovu opciju jer troši više resursa, a ne donosi dodatne prednosti.
Zaključak
Python je jedan od najčešće korišćenih programskih jezika za automatizaciju procesa interakcijom sa operativnim sistemom. Jedna od korisnih stvari koje možete da uradite je provera da li datoteka ili fascikla postoji.
Najjednostavnije metode za to su:
- Otvaranje datoteke i rukovanje izuzecima odmah.
- Korišćenje `exists()` funkcije `os.path` modula ili `pathlib` modula.
U ovom vodiču ste naučili:
- Kako otvoriti datoteku i rukovati izuzecima u slučaju da ona ne postoji.
- Značenje putanja.
- Tri različite funkcije koje `os.path` podmodul nudi za proveru postojanja datoteke ili fascikle.
- Unix koristi kose crte (`/`), dok Windows koristi obrnute kose crte (`\`).
Sledeće čitanje: Šta je subprocess u Python-u? [5 primera upotrebe]