with open(...) as f: — to standardowy sposób pracy z plikami za pośrednictwem menedżera kontekstu. Takie podejście zapewnia, że Python automatycznie zamyka plik po wyjściu z bloku with, nawet jeśli wystąpi wyjątek. Eliminuje to wycieki deskryptorów plików i blokady plików.
Wewnątrz bloku można pracować z plikiem, używając metod obiektu (f.read(), f.write() itd.). Po wyjściu z bloku (nawet w przypadku błędu) wywoływana jest metoda f.close().
Przykład:
with open('data.txt', 'w') as f: f.write('Hello!') # Tutaj plik jest już zamknięty
Częste pytanie:
Czy możemy być pewni, że plik otwarty przez
openzostanie zamknięty natychmiast po wyjściu z blokuwith, nawet jeśli wystąpi wyjątek w środku bloku?
Odpowiedź: Tak, dokładnie to gwarantuje kontrakt menedżera kontekstu: niezależnie od wyjątków, metoda __exit__ jest wywoływana przy wyjściu z bloku, co prowadzi do zamknięcia pliku. To jest główna zaleta w porównaniu do jawnego wywołania f.close().
Historia
Na dużym projekcie zapisy do logu odbywały się przez open('log.txt', 'a') oraz jawne wywołanie f.write(), ale zapominali o f.close(). Po długiej pracy proces wykorzystał wszystkie deskryptory plików systemu operacyjnego, a usługa przestała działać.
Historia
W systemie monitorującym używano ciągłego otwierania plików przez open, nie przetwarzano wyjątków. W przypadku wystąpienia błędu plik pozostawał otwarty, co prowadziło do blokad podczas próby ponownego otwarcia z innego procesu.
Historia
Programista zrealizował odczyt dużego pliku przez open i od razu wykonał return w środku funkcji, nie zamykając pliku. W wyniku kilku takich operacji doszło do przepełnienia zasobów plików, a system operacyjny zaczął blokować nowe otwarcia.