Ćwiczenie: lista zakupów zapisana w pliku i policzona
Rozgrzewka · 3 minuty
Co pamiętacie z lekcji 14?
Czym różni się słownik od listy?
Jak dodać do słownika prices parę: klucz „ser”, wartość 12.0?
Co sprawdza zapis "chleb" in prices?
Część 1 · Po co plik
Dane, które zostają po zamknięciu programu
Zmienne i słowniki żyją tylko tak długo, jak działa program: po jego zakończeniu pamięć jest sprzątana i dane znikają. Plik to miejsce na dysku, które zostaje. Zmienna jest jak to, co pamiętacie w czasie lekcji, a plik jak zeszyt, który zabieracie do domu.
Plik otwiera funkcja open. W nawiasie podajemy nazwę pliku, tryb (co zamierzamy z nim zrobić) i kodowanie: open(nazwa, tryb, encoding=...).
docs.python.org, The Python Tutorial, rozdz. 7.2 (Reading and Writing Files)
Część 1 · with open
Trzy rzeczy w nawiasie: nazwa, tryb, kodowanie
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Ala\n")
print(f.closed)
Na ekranie: True
"notes.txt" to nazwa pliku, "w" to tryb, czyli zamiar: zapis.
as f nadaje nazwę uchwytowi: przez f sięgamy do pliku, a nie do jego treści.
with zamyka plik po wyjściu z bloku, także wtedy, gdy program zgłosi błąd.
W praktyce: dopisanie litery b do trybu ("rb", "wb") otwiera plik binarny: dane są wtedy bajtami, a kodowania nie podaje się wcale. Tak czyta się zdjęcia i pliki muzyczne.
docs.python.org, The Python Tutorial, rozdz. 7.2 (Reading and Writing Files)
Część 2 · Zapis
write pisze dokładnie to, co dostanie
Z \n na końcu
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Ala\n")
f.write("Ola\n")
W pliku: Ala i Ola w dwóch liniach
Bez \n
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Ala")
f.write("Ola")
W pliku: AlaOla w jednej linii
Znak \n to znak nowej linii: w pliku tekstowym on jeden decyduje, gdzie kończy się linia. Funkcja write oddaje liczbę zapisanych znaków, więc f.write("Ala\n") daje 4.
docs.python.org, The Python Tutorial, rozdz. 7.2.1 (Methods of File Objects)
Część 2 · Tryby otwarcia
Trzy litery, trzy różne skutki
Tryb
Co robi
Gdy pliku nie ma
"r"
tylko czytanie, tryb domyślny
błąd FileNotFoundError
"w"
tylko zapis, stara zawartość zostaje wymazana
tworzy nowy plik
"a"
dopisanie: nowe dane trafiają na koniec
tworzy nowy plik
docs.python.org, The Python Tutorial, rozdz. 7.2 (Reading and Writing Files)
Część 3 · Czytanie
Cały plik naraz albo lista linii
with open("notes.txt", "r", encoding="utf-8") as f:
text = f.read()
print(text, end="")
Na ekranie: Ala Ola
with open("notes.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
print(lines)
Na ekranie: ['Ala\n', 'Ola\n']
Funkcja read oddaje całą zawartość jako jeden napis. Funkcja readlines oddaje listę: jeden element to jedna linia, razem ze znakiem \n na końcu.
docs.python.org, The Python Tutorial, rozdz. 7.2.1 (Methods of File Objects)
Część 3 · Linia po linii
Pętla po pliku i licznik linii
count = 0
with open("shopping.txt", "r", encoding="utf-8") as f:
for line in f:
print(line, end="")
count = count + 1
print("Produktów:", count)
Na ekranie:
chleb mleko jabłka Produktów: 3
Bez end="" między produktami pojawiłyby się puste linie: linia z pliku ma już swój \n, a print dołożyłby drugi.
W praktyce: słownika nie zapisuje się do pliku ręcznie. Moduł json robi to jednym poleceniem: json.dump(prices, f) zapisuje, a json.load(f) odczytuje i oddaje gotowy słownik.
docs.python.org, The Python Tutorial, rozdz. 7.2.1 (Methods of File Objects) · rozdz. 7.2.2 (Saving structured data with json)
Ćwiczenie · przy komputerze · 12 minut
Ćwiczenie: lista zakupów w pliku
Napisz program save.py: zapisz do pliku shopping.txt trzy produkty, każdy w osobnej linii. Uruchom go i otwórz plik w edytorze.
Napisz program show.py: wczytaj cały plik funkcją read do zmiennej text i wypisz go na ekran.
Dopisz w show.py licznik linii i wypisz „Produktów: …”. Potem dopisz do pliku czwarty produkt trybem "a" i uruchom program jeszcze raz.
Jak to sprawdzić
Uruchom save.py dwa razy pod rząd: plik dalej ma trzy linie, bo tryb "w" za każdym razem kasuje starą zawartość. Uruchom dopisanie dwa razy: linii jest pięć, bo tryb "a" nic nie kasuje.
Sprawdzenie
Trzy pytania na koniec
Po co otwieramy plik zapisem with open(...), zamiast samym open(...)?
Czym różni się tryb "w" od trybu "a"?
Dlaczego przy wypisywaniu linii z pliku piszemy print(line, end="")?
Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
with open(...)
Program zamyka plik nawet po błędzie, więc zapis nie urywa się w połowie
standard
Tryb "a"
Dziennik zdarzeń serwera dopisuje kolejne linie na koniec i nigdy nie kasuje starych
codziennie
encoding="utf-8"
Jedno kodowanie w całym projekcie, żeby „ó” nie zmieniło się w krzaczki na innym systemie
standard
Pętla for line in f
Pliki z milionami linii czyta się po jednej, bo cała zawartość nie mieści się w pamięci