7 sposobów sprawdzenia, czy plik lub folder istnieje w Pythonie

Photo of author

By maciekx

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