Różnorodne Metody Weryfikacji Istnienia Pliku lub Katalogu w Pythonie
Standardowa biblioteka Pythona udostępnia szeroki zakres narzędzi, które umożliwiają programistom efektywne rozwiązywanie problemów. W tym poradniku przeanalizujemy różne sposoby sprawdzania dostępności plików i katalogów, wykorzystując wyłącznie wbudowane moduły językowe.
Weryfikacja, czy dany plik lub skrypt znajduje się we właściwej lokalizacji, ma kluczowe znaczenie dla prawidłowego funkcjonowania każdego programu działającego w trybie wiersza poleceń. Twój program może stać się całkowicie bezużyteczny, jeśli w trakcie jego działania zabraknie określonego pliku.
W dzisiejszym przewodniku pokażemy kilka szybkich i efektywnych technik na to, jak sprawdzić, czy konkretny plik lub folder istnieje w Pythonie.
Zanim Przejdziemy Dalej
Zanim zaczniesz stosować którekolwiek z poniższych poleceń, upewnij się, że masz zainstalowanego Pythona w wersji 3 lub wyższej. Otwórz terminal i wprowadź następującą komendę:
python --version # Python 3.9.5, mój wynik
Jeśli korzystasz z wersji 2.x, musisz użyć polecenia „python3”. Jeśli nie masz zainstalowanego Pythona 3, zajrzyj do naszego przewodnika instalacji.
W tym samouczku wykorzystamy pewne pliki testowe. Upewnij się, że masz utworzone następujące zasoby:
touch testfile.txt mkdir testdirectory/ touch testdirectory/otherfile.txt
Powyższe polecenia stworzą plik, folder testowy oraz dodatkowy plik w folderze testowym. Pliki mogą być puste, ponieważ nie będziemy odczytywać ich zawartości.
Uwaga: Jeśli pracujesz w systemie Windows, możesz stworzyć strukturę plików za pomocą graficznego menedżera plików.
Do interaktywnej pracy z Pythonem posłużymy się Ipythonem, który oferuje wygodny interfejs. Jest to tylko opcja dodatkowa, a nie wymóg.
pip install ipython
Po wykonaniu tej komendy uzyskasz dostęp do wygodnej powłoki Pythona, wpisując po prostu „ipython”.
Teraz, gdy wszystko jest gotowe, przejdźmy do sposobów weryfikacji istnienia plików i folderów w Pythonie.
Próba Otwarcia Pliku i Obsługa Wyjątku
Jest to najprostsza metoda. W sytuacji, gdy próbujesz otworzyć plik, który nie istnieje, Python zgłosi błąd FileNotFoundError.
In [1]: open('nie-ma-mnie.txt') --------------------------------------------------------------------------- FileNotFoundError: [Errno 2] No such file or directory: 'nie-ma-mnie.txt'
Możemy to wykorzystać, obsługując wyjątek, gdy poszukiwany plik nie istnieje.
In [2]: try: ...: file = open('nie-ma-mnie.txt') ...: print(file) # Uchwyt pliku ...: file.close() ...: except FileNotFoundError: ...: print('Przepraszam, szukany plik nie istnieje') ...: exit() ...: Przepraszam, szukany plik nie istnieje
W powyższym kodzie, jeśli plik nie istnieje, wyświetlamy niestandardowy komunikat i kończymy działanie programu.
Zwróć uwagę, że funkcja `exit()` zostanie wykonana tylko w przypadku wystąpienia wyjątku. Zobaczmy, co stanie się, gdy poszukiwany plik faktycznie istnieje.
In [2]: try: ...: file = open('testfile.txt') ...: print(file) # Uchwyt pliku ...: file.close() ...: except FileNotFoundError: ...: print('Przepraszam, szukany plik nie istnieje') ...: exit() ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Zauważ, że zamykamy plik zaraz po jego otwarciu. Jest to uważane za dobrą praktykę, zgodnie z dokumentacją Pythona.
Wywołanie `file.write()` bez użycia słowa kluczowego `with` lub wywołania `file.close()` może sprawić, że dane przekazywane do `file.write()` nie zostaną w całości zapisane na dysku, nawet jeśli program zakończy się sukcesem.
Nawet jeśli nie zapisujemy danych do pliku, zaleca się jego zamykanie, gdyż w przeciwnym razie może to prowadzić do problemów z wydajnością.
Jeśli nie chcesz samodzielnie zamykać pliku, skorzystaj z menedżera kontekstu. Automatycznie przydziela on i zwalnia zasoby, dzięki czemu nie musisz zamykać pliku ręcznie.
In [3]: try: ...: with open('testfile.txt') as file: ...: print(file) ...: # Nie trzeba zamykać pliku ...: except FileNotFoundError: ...: print('Przepraszam, szukany plik nie istnieje') ...: exit() ...: ...: <_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>
Metoda ta jest wyjątkowo przydatna przy zapisie danych do plików, ale mało efektywna, jeśli chcemy tylko zweryfikować, czy plik istnieje. Przyjrzyjmy się innym metodom osiągnięcia tego celu.
`os.path.exists()`
Moduł „os” (system operacyjny) oferuje szereg funkcji do interakcji z systemem operacyjnym. Do sprawdzenia istnienia pliku lub katalogu możemy użyć funkcji `path.exists()`, która przyjmuje jako argument ścieżkę do pliku lub katalogu. Funkcja zwraca wartość logiczną (True/False) w zależności od tego, czy ścieżka istnieje, czy nie.
Uwaga: Ścieżka to unikalna lokalizacja pliku lub katalogu w systemie plików.
W Pythonie podmoduł `os.path` zawiera funkcje służące do pracy ze ścieżkami plików. Wszystkie te funkcje przyjmują ścieżkę w postaci łańcucha znaków lub bajtów. Możemy operować na ścieżkach bezwzględnych, na przykład:
/home/daniel/.bashrc
Lub na ścieżkach względnych, w zależności od katalogu, w którym uruchamiasz skrypt:
.bashrc # Uruchomienie skryptu w moim folderze domowym
Oto kilka przykładów użycia funkcji `os.path.exists()` działającej w katalogu, gdzie znajdują się pliki testowe:
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('nie-ma-mnie') Out[4]: False
Jak widać, funkcja zwraca True w przypadku pliku „testfile.txt” i folderu „testdirectory”, a False, gdy plik nie istnieje.
`os.path.isfile()`
Jeśli chcesz tylko sprawdzić, czy dany plik istnieje (a nie katalog), użyj funkcji `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('w-ogole-nie-istnieje') Out[4]: False In [5]: os.path.isfile('testdirectory/otherfile.txt') Out[5]: True
Uwaga: W systemach UNIX wszystkie katalogi kończą się ukośnikiem (/), natomiast w systemie Windows używany jest ukośnik wsteczny (\).
W powyższym kodzie funkcja `isfile()` zwraca False w dwóch przypadkach. Zobaczmy dlaczego:
- `testdirectory/` jest katalogiem, więc nie jest traktowany jako plik. Nie jest to do końca prawda, ponieważ w Linuksie wszystko jest deskryptorem pliku, ale Python traktuje katalogi inaczej, aby było wygodniej (jeśli spróbujesz otworzyć katalog, otrzymasz IsADirectoryError).
- `w-ogole-nie-istnieje` odnosi się do pliku, który, jak na ironię, nie istnieje.
`os.path.isdir()`
Aby zweryfikować, czy katalog znajduje się we właściwym miejscu, należy użyć funkcji `os.path.isdir()`, która zwraca True tylko wtedy, gdy podana ścieżka wskazuje na katalog.
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('innyplik.txt') Out[4]: False
Zwróć uwagę, że powyższe przykłady zwracają False, nawet jeśli ścieżka odnosi się do istniejącego pliku.
Moduł Glob
Moduł `glob` oferuje funkcje do pracy z wzorcami podobnymi do powłoki systemu Unix (z tego powodu może nie działać poprawnie w systemie Windows). Do sprawdzenia, czy plik pasuje do wzorca w bieżącym katalogu, można użyć metody `glob.glob()`.
In [1]: import glob In [2]: glob.glob('testfile.txt') Out[2]: ['testfile.txt'] In [3]: glob.glob('testdirectory') Out[3]: ['testdirectory']
W powyższym kodzie wzorzec przekazany do funkcji `glob` to zwykły ciąg znaków reprezentujący ścieżkę do pliku i folderu testowego. Ponieważ obie ścieżki istnieją, funkcja zwraca listę zawierającą pasujące nazwy ścieżek.
Uwaga: Jeśli wzorzec nie pasuje, otrzymasz pustą listę.
Biorąc pod uwagę, że możemy przekazywać wzorce do funkcji `glob`, zobaczmy, jak można wykorzystać tę funkcjonalność:
Poniższy kod pobiera wszystkie ścieżki plików z rozszerzeniami .txt i .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']
Klasa Path
Klasa `Path` jest jednym z najlepszych sposobów pracy ze ścieżkami, ponieważ oferuje przejrzysty interfejs do obsługi ścieżek plików jako obiektów.
Instancje `Path` posiadają wszystkie metody niezbędne do uzyskania informacji o określonej ścieżce. Obejmuje to funkcjonalności podobne do omówionych wcześniej opcji.
Uwaga: Do korzystania z biblioteki `pathlib` wymagany jest Python w wersji 3.4 lub nowszej.
Metody klasy `Path`, które będziesz używać:
Sprawdzenie istnienia ścieżki
In [1]: from pathlib import Path In [2]: Path('testfile.txt').exists() Out[2]: True In [3]: Path('nie-ma-mnie.txt').exists() Out[3]: False In [4]: Path('testdirectory').exists() Out[4]: True
Działa to analogicznie do `os.path.exists()`.
Sprawdzenie, czy ścieżka wskazuje na plik
In [5]: Path('testfile.txt').is_file() Out[5]: True In [6]: Path('testdirectory').is_file() Out[6]: False
Odpowiednik `os.path.isfile()`.
Sprawdzenie, czy ścieżka wskazuje na katalog
In [7]: Path('testfile.txt').is_dir() Out[7]: False In [8]: Path('testdirectory').is_dir() Out[8]: True
Odpowiada funkcji `os.path.isdir()`.
Moduł Subprocess
Jeżeli jesteś fanem modułu `subprocess`, na pewno zainteresuje Cię ta opcja. Możesz sprawdzić istnienie pliku lub folderu za pomocą polecenia testowego.
Uwaga: Polecenie `test` działa tylko w systemach Unix.
Następujące flagi testowe wykonają zadanie:
- `test -e`: Sprawdź, czy ścieżka istnieje
- `test -f`: Sprawdź, czy plik istnieje
- `test -d`: Sprawdź, czy folder istnieje
Jeśli chcesz zagłębić się w szczegóły polecenia `test`, możesz przeczytać instrukcję, wpisując:
man test
Sprawdzenie ścieżki za pomocą podprocesu:
Poniższy kod weryfikuje, czy ścieżka istnieje, porównując kod powrotu podprocesu z wartością 0.
Pamiętaj, że w Linuksie proces, który zakończył się powodzeniem, zwraca zero. W przeciwnym razie zwracany jest inny kod.
In [1]: from subprocess import run In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0 Out[2]: True In [3]: run(['test', '-e', 'nie-ma-mnie.txt']).returncode == 0 Out[3]: False
W pierwszej instrukcji importujemy moduł `subprocess`, a następnie używamy funkcji `run()`, aby uzyskać kod powrotu.
Weryfikacja istnienia pliku za pomocą subprocess
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0 Out[4]: True In [5]: run(['test', '-f', 'testdirectory']).returncode == 0 Out[5]: False
Sprawdzanie katalogu za pomocą podprocesu:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0 Out[6]: False In [7]: run(['test', '-d', 'testdirectory']).returncode == 0 Out[7]: True
Nie zaleca się korzystania z tej opcji, ponieważ zużywa więcej zasobów, nie dając żadnych dodatkowych korzyści.
Podsumowanie
Python jest jednym z najpopularniejszych języków programowania, wykorzystywanych do automatyzacji procesów poprzez interakcję z systemem operacyjnym. Jedną z przydatnych czynności jest sprawdzanie, czy dany plik lub folder istnieje.
Najprostsze sposoby osiągnięcia tego celu to:
- Natychmiastowe otwieranie plików i obsługa ewentualnych wyjątków.
- Użycie funkcji `exists()` z modułów `os.path` lub `pathlib`.
W tym poradniku nauczyłeś się:
- Jak otworzyć plik i obsłużyć wyjątek, gdy on nie istnieje.
- Znaczenia ścieżek.
- Trzech różnych funkcji, które oferuje moduł `os.path` do sprawdzania istnienia plików i folderów.
- W systemach Unix używa się ukośników (/), natomiast w systemach Windows stosuje się ukośniki wsteczne (\).
Następny artykuł: Co to jest podproces w Pythonie? [5 przykładów użycia]
newsblog.pl
Maciej – redaktor, pasjonat technologii i samozwańczy pogromca błędów w systemie Windows. Zna Linuxa lepiej niż własną lodówkę, a kawa to jego główne źródło zasilania. Pisze, testuje, naprawia – i czasem nawet wyłącza i włącza ponownie. W wolnych chwilach udaje, że odpoczywa, ale i tak kończy z laptopem na kolanach.