Bestanden lezen en schrijven · oefening
Tekst veilig lezen
Een pad beantwoordt de vraag “welk bestand?” Daarna volgen “welke soort toegang?” en “hoe moeten deze bytes tekst worden?”
Dit is de volledige overgang naar het bestand die je in deze les bouwt:
with open(path, "r", encoding="utf-8") as handle:
# read from handle here
Lees die eerste regel van binnen naar buiten:
pathis het te openen bestand;"r"betekent leesmodus;encoding="utf-8"legt vast hoe opgeslagen bytes Python-strings worden;as handlegeeft het geopende bestand een tijdelijke naam.
Waarom with de handle beheert
Een geopend bestand is een hulpbron van het besturingssysteem. Het moet worden gesloten wanneer het werk klaar is, ook als het lezen halverwege mislukt.
De with-instructie maakt die levensduur zichtbaar. Python opent het bestand voordat het ingesprongen blok begint en sluit het wanneer het blok eindigt. Het sluit het bestand ook als een exception het blok voortijdig verlaat. Je hebt geen losstaande handle.close() verderop nodig die een nieuwe return of fout per ongeluk kan overslaan.
Dit is een contextmanager: de waarde die open(...) oplevert, weet hoe je een beheerd blok veilig binnengaat en verlaat. Later kom je andere contextmanagers tegen. Voor nu is de blijvende regel klein: hoort een bestandshandle bij één bewerking, zet die bewerking dan binnen with.
Regels lezen zonder lege records te bewaren
data/books.txt bevat één titel per regel en één opzettelijk lege regel. Door over de handle te itereren krijg je elke regel als tekst, inclusief de afsluitende newline. .strip() verwijdert de witruimte eromheen. Een leeg resultaat hoort geen lege boektitel te worden.
Bouw het resultaat op met de lijsten en lussen die je al kent:
books = []
for line in handle:
title = line.strip()
if title:
books.append(title)
Gebruik de parameter path, niet BOOKS_PATH. Het is verleidelijk om de constante bovenaan het bestand te pakken, maar een functie die maar één bepaald bestand leest is niet herbruikbaar. De volgende hoofdstukken geven deze functie verschillende bestanden mee. Schrijf haar zo dat ze leest wat ze krijgt.
De codering hoort bij het bestandscontract
UTF-8 kan de titel Cien años de soledad, met tekens buiten ASCII, en gewone Engelse tekst in één overdraagbare codering weergeven. Vertrouw je op de standaardinstelling van een computer, dan kunnen dezelfde bytes op verschillende computers verschillend worden geïnterpreteerd.
encoding="utf-8" is geen foutherstel. Het is een expliciete afspraak. Als de bytes van een bestand geen geldige UTF-8 zijn, werpt Python een UnicodeDecodeError op; in de volgende les bepalen we waar die verwachte fout bij het lezen moet worden afgehandeld.
Maak read_books(path) af in de projecteditor en lever je werk in.
Loop je vast bij de lus, vraag Monty dan wat line.strip() teruggeeft voor een regel die alleen een newline bevat. Die ene waarde verklaart waarom je de lege regel moet afhandelen.
Wat geeft de with-instructie je dat een losse open niet geeft?
Waarom geef je encoding="utf-8" mee in plaats van op de standaardinstelling te vertrouwen?
Opdracht
Implementeer read_books(path).
Open de meegegeven
pathexpliciet in leesmodus met UTF-8-codering.Beheer de geopende handle met een
with-instructie.Geef een lijst terug met bijgesneden, niet-lege regels in de oorspronkelijke volgorde.
Gebruik de parameter; leg
BOOKS_PATHof de meegeleverde titels niet vast in de functie.
Laat de andere functies staan voor latere lessen.