- Leren
- Informatica & ICT
- Programmeren
- Inleiding tot programmeren met Python
- Bestanden en excepties in Python
Bestanden en excepties in Python
with-instructies, en vind bestanden met relatieve en absolute paden en pathlib. Lees en schrijf CSV-gegevens met de module csv, ook met rijen als dictionary’s. Vang daarna verwachte fouten op met try en except, gebruik else en finally, werp je eigen excepties op met duidelijke meldingen en bouw programma’s die ontbrekende bestanden en ongeldige gegevens melden in plaats van vast te lopen.BeginnerLes 8 van 10 in Cursus Inleiding tot programmeren met Python
Wat je leert
- Open tekstbestanden, lees hun inhoud op een manier die bij de taak past, schrijf tekst en voeg tekst toe zonder gegevens te verliezen, en verwerk een bestand regel voor regel om te zoeken, tellen en filteren.
- Open een tekstbestand en lees de inhoudGebruik
open()om een programma met een tekstbestand te verbinden, kies de juiste manier om het te lezen en zet de gelezen tekst om in bruikbare gegevens. - Sluit bestanden automatisch met de with-instructieGebruik
with open(...) as f:zodat bestanden op het juiste moment worden gesloten, ook als er iets misgaat. - Schrijf tekst naar bestanden en voeg tekst toeKies de juiste modus om een bestand te maken, te overschrijven of uit te breiden, en schrijf tekst met
write()enprint()zodat de regels er precies zo uitzien als bedoeld. - Doorzoek, tel en filter regels in een bestandVerwerk een bestand regel voor regel om de benodigde regels te vinden, ze te tellen of op te tellen en de resultaten naar een nieuw bestand te schrijven.
- Open een tekstbestand en lees de inhoud
- Vertel Python precies waar een bestand staat, begrijp waarom een programma een bestaand bestand soms niet kan vinden en stel paden samen die werken op Windows, macOS en Linux.
- Gebruik relatieve en absolute paden correctSchrijf absolute en relatieve paden, weet vanuit welke map een relatief pad begint en vermijd de valkuilen van backslashes in Windowspaden.
- Stel paden samen en beheer mappen met pathlibGebruik
Path-objecten uit de modulepathlibom paden samen te voegen, te bekijken en te controleren, bestanden te vinden, mappen aan te maken en kleine bestanden in één stap te lezen of te schrijven.
- Gebruik relatieve en absolute paden correct
- Gebruik de Pythonmodule
csvom tabelgegevens uit CSV-bestanden te lezen, ze om te zetten in getallen en resultaten terug te schrijven als CSV die spreadsheetprogramma’s kunnen openen.- Lees CSV-gegevens met csv.readerBegrijp hoe een CSV-bestand een tabel opslaat, lees het rij voor rij met
csv.reader, sla de kopregel over en converteer de waarden die je nodig hebt. - Schrijf CSV-bestanden met csv.writerMaak CSV-bestanden van lijsten met
csv.writer, zodat komma’s, aanhalingstekens en regelafsluitingen correct worden verwerkt. - Benader kolommen via hun naam met DictReader en DictWriterLees elke CSV-rij als een dictionary met de kolomnamen uit de kopregel als sleutels, filter rijen en vat ze samen op kolomnaam, en schrijf dictionary’s terug naar CSV.
- Lees CSV-gegevens met csv.reader
- Herken de excepties die Python opwerpt, lees een stacktrace om de oorzaak te vinden, vang de fouten op die je verwacht en laat een programma doorlopen of stop het met een duidelijke melding in plaats van het te laten vastlopen.
- Herken veelvoorkomende excepties en lees een stacktraceWeet wat een exceptie is, lees een stacktrace van onder naar boven en noem de veelvoorkomende exceptietypen met hun gebruikelijke oorzaken.
- Vang excepties op met try en exceptSchrijf
try- enexcept-blokken die de specifieke fouten opvangen die je verwacht, de gebruiker een bruikbare melding geven en onverwachte fouten zichtbaar laten worden. - Gebruik else en finally en volg excepties door functies heenVul een
try-instructie aan metelseenfinally, voorspel in welke volgorde de blokken worden uitgevoerd en bepaal in welke functie een exceptie moet worden afgehandeld. - Zorg voor gecontroleerde foutafhandeling in programma’s die bestanden en gegevens verwerkenCombineer bestandsverwerking en exceptieafhandeling zodat ontbrekende bestanden, geblokkeerde bestanden en ongeldige gegevens leiden tot duidelijke meldingen, overgeslagen rijen of een gecontroleerde stop in plaats van een vastgelopen programma.
- Herken veelvoorkomende excepties en lees een stacktrace
- Gebruik
raiseom te voorkomen dat een functie doorgaat met ongeldige invoer, kies passende exceptietypen en meldingen en geef fouten door of zet ze om in duidelijkere fouten.- Werp excepties op om ongeldige invoer af te wijzenGebruik de
raise-instructie om aan te geven dat een functie een waarde heeft ontvangen waarmee ze niet kan werken, en laat de aanroepende code beslissen hoe erop wordt gereageerd. - Werp excepties opnieuw op, koppel ze en definieer je eigen exceptiesGeef een exceptie door nadat je erop hebt gereageerd, zet een onderliggende fout om in een duidelijkere fout en maak je eigen exceptietypen voor problemen die specifiek zijn voor je programma.
- Werp excepties op om ongeldige invoer af te wijzen
Bestanden en excepties in Python: uitleg
1Lees en schrijf tekstbestanden
Met bestanden kan een programma informatie tussen uitvoeringen bewaren en werken met gegevens die elders zijn verzameld. Door te lezen haal je tekst in het geheugen; door te schrijven bewaar je resultaten voor de volgende uitvoering of voor iemand anders. Je kiest een leesmethode, bepaalt precies wat er wordt geschreven en gebruikt inspringing om bestanden alleen open te houden zolang ze nodig zijn. Voorbeelden die regels een voor een verwerken, combineren daarna stringbewerkingen, keuzes en tellers om ruwe tekst om te zetten in bruikbare resultaten.
1.1 Tekst in een programma lezen
Een tekstbestand bewaart informatie nadat een programma stopt. Python gebruikt een bestandsobject, teruggegeven door open(), om met die informatie te werken. Openen verbindt het programma met het bestand; een leesbewerking haalt de tekst op.
Kies wat je leest
De standaardmodus is "r", voor lezen. Een losse naam wordt opgezocht in de huidige werkmap. Als het bestand daar ontbreekt, werpt open() FileNotFoundError op.
with open("fruit.txt", encoding="utf-8") as f:
text = f.read()
Stel dat het bestand drie regels heeft, “apple”, “banana” en “cherry”, allemaal met een regelafsluiting. text is 'apple\nbanana\ncherry\n'. De escapesequentie \n stelt één regeleindeteken voor. Een laatste regel kan ook zonder regeleindeteken eindigen.
| Bewerking | Resultaat | Handig wanneer |
|---|---|---|
f.read() | Alle resterende tekst als één string | Je een klein bestand in zijn geheel nodig hebt |
f.readline() | De volgende regel als string | Je nu één regel nodig hebt |
f.readlines() | Alle resterende regels als lijst | Je de regels opnieuw wilt gebruiken |
for line in f: | Eén regel per iteratie | Je regels op volgorde kunt verwerken |
readline() geeft '' terug aan het einde van het bestand. Een lege regel met een regelafsluiting geeft '\n' terug, dus een lege regel en het einde van het bestand zijn verschillend.
Houd de positie bij
Door te lezen gaat de bestandspositie vooruit. Nadat f.read() het bestand heeft uitgelezen, geeft een volgende aanroep '' terug; een lus over datzelfde object heeft niets meer te lezen. Open het bestand opnieuw om opnieuw te beginnen, of bewaar de benodigde tekst of regels in een variabele. read() en readlines() laden de rest van het bestand in het geheugen. Door rechtstreeks over het bestand te lopen, kun je een groot bestand regel voor regel verwerken.
Regels behouden hun regeleindetekens. print(line) voegt zelf een regeleindeteken toe, waardoor extra lege regels op het scherm kunnen ontstaan. Gebruik print(line, end="") om de oorspronkelijke regelafstand te behouden, of verwijder de regelafsluiting vóór het afdrukken. line.rstrip("\n") verwijdert regeleindetekens aan het einde; line.strip() verwijdert ook spaties aan beide uiteinden.
Zet tekst om in getallen
Zelfs cijfers komen binnen als strings. Dit bestand bevat de scores “72”, “85” en “90”:
scores = []
with open("scores.txt", encoding="utf-8") as f:
for line in f:
scores.append(int(line))
total = sum(scores)
print(total, round(total / len(scores), 2))
De lijst is [72, 85, 90], dus drukt het programma 247 82.33 af. int() accepteert spaties en regeleindetekens rondom de waarde. Een lege string of een woord zoals "forty" werpt ValueError op.
Lees tekens met de juiste tekencodering
Een tekencodering koppelt tekens aan opgeslagen bytes. UTF-8 kan tekens zoals “é” en emoji weergeven. Gebruik voor UTF-8-bestanden expliciet encoding="utf-8". Python 3.15 schakelt standaard de UTF-8-modus in; oudere installaties kunnen een lokale tekencodering gebruiken. Een onjuiste tekencodering kan verminkte tekst of UnicodeDecodeError opleveren. Een expliciete tekencodering zet een bestand dat met een andere codering is opgeslagen niet om naar UTF-8.
Het with-blok sluit het bestand wanneer het eindigt. Een gesloten bestand kan niet worden gelezen: een volgende f.read() werpt ValueError op.
Belangrijkste punten
open()geeft een bestandsobject terug; lezen haalt tekst op vanaf de huidige positie.- Kies een string, een lijst met regels of een lus die regels een voor een verwerkt, passend bij de taak.
- Het einde van een bestand geeft
''; een lege regel kan'\n'geven. - Zet numerieke tekst vóór het rekenen om met
int()offloat(). - Gebruik de tekencodering die bij het bestand past en sluit het als je klaar bent.
1.2 Bestanden die sluiten wanneer het blok eindigt
Een open bestand gebruikt bronnen van het besturingssysteem. Tekst die wordt geschreven, kan ook in een buffer in het geheugen wachten voordat die het bestand bereikt. Sluiten geeft de bronnen vrij en schrijft de gebufferde uitvoer weg. Een with-instructie regelt dat opruimen op een duidelijke plek in de code.
Lees binnen het blok, gebruik het resultaat daarna
with open("notes.txt", encoding="utf-8") as f:
text = f.read()
print(len(text))
De dubbele punt begint het blok. De ingesprongen regel wordt uitgevoerd terwijl f open is. Wanneer de uitvoering de niet-ingesprongen print() bereikt, is het bestand gesloten, maar blijft text een gewone string. De naam f verwijst nog steeds naar het bestandsobject; f.closed is nu True.
Hetzelfde patroon werkt voor een lijst:
with open("fruit.txt", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip().upper())
De lus gebruikt gegevens die al in lines zijn ingelezen. Als je f.readlines() buiten het blok zou plaatsen, zou die proberen een gesloten bestand te lezen en ValueError opwerpen.
Opruimen wanneer het uitvoeringsverloop verandert
Bekijk een functie die de eerste regel teruggeeft:
def first_line(path):
with open(path, encoding="utf-8") as f:
return f.readline().rstrip("\n")
De retourwaarde wordt binnen het blok voorbereid. Python verlaat daarna het blok en sluit het bestand voordat de aanroepende code die waarde ontvangt. Het bestand sluit ook wanneer een exceptie het blok verlaat. Een handmatige f.close() na een instructie die een fout veroorzaakt, zou nooit worden bereikt.
Bestandsobjecten ondersteunen dit gedrag omdat het contextbeheerders zijn: objecten die de voorbereiding en het opruimen rond een with-blok regelen. Je kunt dat gedrag gebruiken zonder zelf een contextbeheerder te schrijven.
Open samen een invoer- en een uitvoerbestand
with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
for line in src:
dst.write(line.upper())
Elke invoerregel wordt omgezet naar hoofdletters en naar de uitvoer geschreven. Beide bestanden sluiten wanneer het blok eindigt. Als de tweede opening mislukt, wordt het eerste bestand, dat al door with is geopend, gesloten wanneer Python de instructie verlaat.
Opruimen en foutherstel hebben verschillende taken
with vangt geen bestandsfouten op. Als open() notes.txt niet kan vinden, werpt de functie FileNotFoundError op voordat de inhoud van het blok wordt uitgevoerd. Als het omzetten van een regel met int() binnen het blok mislukt, sluit het bestand en wordt de exceptie verder naar buiten doorgegeven. Voor herstel of het tonen van een melding is een overeenkomende except-clausule nodig.
Een ontbrekende dubbele punt aan het einde van de with-regel veroorzaakt SyntaxError.
Belangrijkste punten
withsluit een geopend bestand bij normaal verlaten, bij terugkeer en wanneer een exceptie het blok verlaat.- Opgeslagen strings en lijsten blijven bruikbaar nadat het bestand is gesloten.
- De inspringing geeft aan hoelang het bestand open is.
- Opruimen vangt geen exceptie op; voor herstel zijn
tryenexceptnodig.
1.3 Tekst maken, vervangen en toevoegen
Schrijven begint met een keuze over bestaande gegevens. De modus bepaalt of Python een bestand leest, vervangt, uitbreidt of aanmaakt. Maak die keuze voordat je open() aanroept, want vervangen gebeurt onmiddellijk.
Kies de modus
| Modus | Bestaand bestand | Ontbrekend bestand |
|---|---|---|
"r" | Opent om te lezen | Werpt FileNotFoundError op |
"w" | Maakt leeg en opent om te schrijven | Maakt het aan |
"a" | Voegt uitvoer toe aan het einde | Maakt het aan |
"x" | Werpt FileExistsError op | Maakt het aan |
Als je de enige kopie van belangrijke gegevens opent met "w", vernietig je de oude inhoud, zelfs als er geen write() volgt. Gebruik een apart uitvoerbestand terwijl je leert gegevens te transformeren. "x" is handig wanneer het vervangen van een bestaand bestand moet worden geweigerd.
Door "b" toe te voegen, zoals in "rb", kies je de binaire modus voor ruwe bytes. Tekstmodi werken met strings en een tekencodering; binaire modi accepteren geen encoding-argument.
Bepaal waar regels eindigen
with open("todo.txt", "w", encoding="utf-8") as f:
f.write("buy milk\n")
f.write("call Sam\n")
Het bestand heeft de twee regels “buy milk” en “call Sam”. write() voegt precies de opgegeven string toe, zonder automatisch scheidingsteken. Zonder de regeleindetekens zou het bestand "buy milkcall Sam" op één regel bevatten.
write() geeft het aantal geschreven tekens terug. Zo geeft f.write("Ana,92\n") 7 terug. Dat is een aantal tekens, niet noodzakelijk het aantal gecodeerde bytes op schijf. De methode accepteert een string; f.write(42) werpt TypeError op. Zet een getal eerst om, bijvoorbeeld met f.write(f"{score}\n").
Vergelijk de hulpmiddelen voor uitvoer
print() kan naar een bestand schrijven:
with open("total.txt", "w", encoding="utf-8") as f:
print("Total:", 247, file=f)
De uitvoertekst is "Total: 247\n". print() zet zijn argumenten om, scheidt ze met spaties en voegt standaard aan het einde een regeleindeteken toe.
writelines() krijgt een sequentie van strings, maar voegt geen regelafsluitingen in. f.writelines(["a", "b"]) schrijft "ab". Om één element per regel te krijgen, neem je een regeleindeteken op in elke string, of voeg je de strings samen met "\n" en voeg je aan het einde een regeleindeteken toe.
Bewaar eerdere uitvoeringen
with open("log.txt", "a", encoding="utf-8") as f:
f.write("Program started\n")
Als er aanvankelijk geen bestand is, leveren twee uitvoeringen twee regels op. Met "w" zou elke uitvoering de eerdere regel vervangen. De toevoegmodus vult geen ontbrekend regeleindeteken aan: als de bestaande tekst midden op een regel eindigt, begint de nieuwe tekst er direct achter.
Voor een rapport doorloop je paren zoals [("Ana", 92), ("Ben", 78)] en schrijf je f"{name}: {score}\n". De opmaak gebeurt vóór het schrijven, dus f"{82.333:.1f}" levert de tekst "82.3" op. Daarna sluit with de uitvoer en schrijft de gebufferde tekst weg aan het einde van het blok.
Belangrijkste punten
"w"maakt een bestaand bestand leeg zodra het wordt geopend."a"voegt toe aan het einde;"x"weigert een bestaand bestand te vervangen.write()krijgt een string en voegt geen regeleindeteken toe.print(..., file=f)zet waarden om en voegt standaard een regeleindeteken toe.writelines()schrijft strings achter elkaar zonder scheidingstekens toe te voegen.- Binaire modi lezen of schrijven bytes en accepteren geen argument voor de tekencodering.
1.4 Bruikbare regels vinden en opslaan
Veel bestandstaken bestaan uit een lus met een keuze erin. Lees een regel, verwijder ongewenste witruimte, bepaal of de regel van belang is en werk een resultaat bij. Door deze stappen gescheiden te houden, maak je een programma gemakkelijker te controleren.
Doorloop een logbestand
Stel dat server.log deze records bevat, met een lege regel vóór het laatste record:
2026-03-01 08:14 INFO Server started
2026-03-01 08:20 ERROR Disk almost full
2026-03-01 09:02 INFO User login: maya
2026-03-01 09:15 WARNING Slow response
2026-03-01 10:40 ERROR Database timeout
2026-03-01 11:05 INFO Backup finished
Elk niet-leeg record heeft een datum, tijd, niveau en bericht. Splits slechts drie keer om het bericht bij elkaar te houden:
errors = 0
with open("server.log", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
parts = line.split(maxsplit=3)
if parts[2] == "ERROR":
errors += 1
print(parts[3])
print(errors, "errors")
Voor het tweede record is parts[2] gelijk aan "ERROR" en parts[3] aan "Disk almost full". Dat bericht wordt afgedrukt en de teller stijgt naar 1. De latere fout verhoogt de teller naar 2. Het programma drukt beide berichten af en daarna “2 errors”.
Controleer het bedoelde deel
| Controle | Wat wordt gevraagd |
|---|---|
line.startswith("From:") | Begint de regel met deze tekst? |
"ERROR" in line | Komt deze tekst ergens voor? |
line.find("ERROR") | Waar komt de tekst voor het eerst voor, of is het resultaat -1? |
parts[2] == "ERROR" | Is dit specifieke veld precies het foutniveau? |
Overal zoeken zou ook overeenkomen met “INFO No ERRORS today”. Controle van het niveauveld beantwoordt de vraag over het logbestand nauwkeuriger.
Na strip() is een lege regel ""; splitsen levert [] op. Als je dan parts[2] met een index benadert, wordt IndexError opgeworpen. De continue slaat die regel over voordat een index wordt gebruikt. Een niet-leeg maar onvolledig record vereist ook een lengtecontrole wanneer zulke records mogelijk zijn.
Tel categorieën of schrijf een gefilterd bestand
Een dictionary bevat een telling per niveau. Stel voor elk record level = parts[2] in en daarna counts[level] = counts.get(level, 0) + 1. Voor het logbestand hierboven zijn de tellingen {'INFO': 3, 'ERROR': 2, 'WARNING': 1}. De standaardwaarde 0 begint een categorie wanneer die voor het eerst verschijnt.
Om overeenkomende records op te slaan, open je een apart doelbestand in dezelfde with-instructie en schrijf je een regel wanneer het niveau overeenkomt. Bewaar de oorspronkelijke line als de witruimte van belang is; als je opgeschoonde tekst schrijft, voeg dan het regeleindeteken weer toe. Open het bronbestand zelf nooit met "w": het zou worden leeggemaakt voordat het lezen begint.
Maak onzichtbare tekens zichtbaar
print(repr(line)) maakt spaties en regeleindetekens aan het einde zichtbaar, bijvoorbeeld 'Disk full \n'. strip() verwijdert beide, terwijl rstrip("\n") de spaties behoudt. Bij gewoon lezen als tekst worden herkende regelafsluitingen van Windows, Unix en oude Macsystemen omgezet naar "\n". Een laatste regel zonder afsluiting blijft zonder afsluiting. Met een bestandsnaam die via input("File name: ").strip() wordt opgehaald, werkt dezelfde lus voor verschillende invoerbestanden.
Belangrijkste punten
- Schoon op, selecteer, verwerk en rapporteer in afzonderlijke stappen.
- Sla lege regels over voordat je gesplitste velden met een index benadert.
- Controleer het bedoelde veld wanneer zoeken in de hele regel te veel overeenkomsten kan opleveren.
- Gebruik een dictionary om per categorie een teller bij te houden.
- Schrijf gefilterde uitvoer naar een ander bestand.
repr()maakt spaties en regeleindetekens zichtbaar die bij gewoon afdrukken verborgen blijven.
2Vind bestanden met paden
Een juiste bestandsnaam is slechts een deel van een locatie. De map waarin een programma start, beïnvloedt relatieve paden en kan verschillen van de map waarin het script staat. Je volgt paden door een mappenboom, voorkomt escapesequenties in Windowsstrings en stelt locaties samen met pathlib. Deze vaardigheden helpen fouten door ontbrekende bestanden te verklaren en laten hetzelfde project op verschillende computers zijn gegevens vinden en uitvoermappen voorbereiden.
2.1 Waar Python naar een bestand zoekt
Een pad beschrijft een locatie in een mappenboom. Het kan beginnen bij de wortel van die boom of bij de huidige werkmap van het programma. Een bestand kan op de computer bestaan en toch ontbreken op de locatie waar je programma om vraagt.
Lees een pad vanaf het beginpunt
| Soort | Voorbeeld | Beginpunt |
|---|---|---|
| Absoluut, macOS of Linux | /Users/maya/data/notes.txt | De wortel / |
| Absoluut, Windows | C:/Users/Maya/data/notes.txt | De wortel van schijf C |
| Relatief | data/notes.txt | Huidige werkmap |
Stel dat een map met de naam project een map scripts en een map data bevat. Je voert python scripts/report.py uit terwijl je in project werkt. Het openen van "data/notes.txt" zoekt in project/data, ook al staat het script in project/scripts.
Als je hetzelfde script daarentegen start terwijl je in project/scripts werkt, verwijst dat relatieve pad naar een locatie in project/scripts/data. Het script is niet verplaatst; het beginpunt is veranderd.
from pathlib import Path
print(Path.cwd())
Dit drukt de huidige werkmap af. os.getcwd() na import os geeft dezelfde informatie als string. Editors en hulpmiddelen om programma’s te starten kunnen een werkmap kiezen, dus bekijk die wanneer de locatie onduidelijk is.
Doorloop mappen
In een relatief pad betekent . de huidige map en .. de bovenliggende map. Vanuit project/scripts gaat ../data/notes.txt omhoog naar project en daarna omlaag naar data. Als je .. toevoegt zonder de beginmap te controleren, kan een programma op de verkeerde locatie terechtkomen.
Een absoluut pad is handig om één exacte locatie aan te geven, maar een pad zoals C:/Users/Maya/Desktop/data.csv bindt gedeelde code aan de mappen van één persoon. Gebruik een relatief pad met een duidelijk beginpunt, of stel het pad samen vanuit de eigen map van het script wanneer de gegevens daar thuishoren.
Houd backslashes van Windows intact
Windows toont gewoonlijk backslashes tussen mappen. In een gewone Pythonstring begint een backslash een escapesequentie: \n wordt een regeleindeteken en \t een tab. De letterlijke waarde "C:\new\table.txt" bevat daarom niet het pad dat je bedoelde.
Deze vormen behouden het bedoelde pad:
raw = r"C:\new\table.txt"
escaped = "C:\\new\\table.txt"
forward = "C:/new/table.txt"
Python op Windows accepteert schuine strepen. Een ruwe string voorkomt dat backslashes escapesequenties worden, maar kan niet eindigen op één enkele backslash. Zo is r"C:\data\" ongeldige syntaxis.
Controleer zowel de naam als de map
Let op verschillen in spelling en verborgen extensies: een bestand dat wordt weergegeven als “notes.txt” kan in werkelijkheid “notes.txt.txt” heten. Ook hoofdletters en kleine letters zijn van belang. Linux maakt meestal onderscheid tussen Data.csv en data.csv; de gebruikelijke instellingen van Windows en macOS doen dat niet. Door de werkelijke hoofdletters en kleine letters over te nemen, blijft een project op verschillende systemen bruikbaar.
Belangrijkste punten
- Relatieve paden beginnen vanuit de huidige werkmap.
- De werkmap kan verschillen van de map van het script.
.blijft in de huidige map;..gaat naar de bovenliggende map.- Gebruik ruwe strings, dubbele backslashes of schuine strepen voor Windowspaden.
- Controleer exacte namen, extensies en hoofdletters en kleine letters wanneer een bestand ontbreekt.
2.2 Paden samenstellen met pathlib
De standaardmodule pathlib geeft een pad een eigen object. Met een Path kun je mapnamen samenvoegen, een bestandsnaam bekijken en veelvoorkomende bestandstaken uitvoeren zonder handmatig strings met scheidingstekens samen te stellen.
Voeg samen en bekijk
from pathlib import Path
p = Path("reports") / "2026" / "sales.csv"
print(p.name)
print(p.stem)
print(p.suffix)
print(p.parent)
De eerste drie resultaten zijn “sales.csv”, “sales” en “.csv”. De bovenliggende map is het pad reports/2026, weergegeven met het scheidingsteken van het systeem. Hier voegt / padonderdelen samen; de operator deelt geen getallen. Het oudere os.path.join() voegt ook padonderdelen als strings samen.
Een Path beschrijft een locatie, ook voordat daar iets bestaat. p.exists() controleert of er iets op die locatie bestaat. p.is_file() en p.is_dir() maken onderscheid tussen een bestand en een map. Een controle op bestaan kan niet garanderen dat later openen lukt: het bestand kan verdwijnen of de toegang kan tussen die bewerkingen veranderen. Handel openingsfouten af wanneer het programma moet kunnen herstellen.
Lees of schrijf een klein bestand
open() accepteert direct een Path. Voor een klein bestand regelen deze hulpmethoden ook het openen en sluiten:
p = Path("greeting.txt")
p.write_text("Hello\n", encoding="utf-8")
text = p.read_text(encoding="utf-8")
text wordt "Hello\n". write_text() vervangt bestaande inhoud, net als openen met "w"; het is geen hulpmethode om tekst toe te voegen. read_text() laadt het hele bestand, dus gebruik een bestandslus wanneer je een groot bestand regel voor regel moet verwerken.
Begin vanuit de map van het script
Een gegevensbestand dat naast een script wordt meegeleverd, moet vanuit dat script worden gevonden, onafhankelijk van de werkmap:
base = Path(__file__).resolve().parent
scores_path = base / "data" / "scores.txt"
with open(scores_path, encoding="utf-8") as f:
scores = f.readlines()
__file__ duidt het scriptbestand aan. resolve() maakt het pad absoluut en parent selecteert de map waarin het staat. In een interactieve shell is __file__ niet gedefinieerd, dus hoort dit patroon in een script thuis.
Vind bestanden en bereid uitvoermappen voor
for p in sorted(Path("logs").glob("*.txt")):
text = p.read_text(encoding="utf-8")
print(p.name, len(text.splitlines()))
glob("*.txt") selecteert overeenkomende paden in logs. iterdir() levert de inhoud van de map zonder dat patroon als filter. Sorteren maakt de volgorde voorspelbaar. splitlines() telt de tekstregels zonder de laatste regelafsluiting als een extra lege regel te behandelen.
Schrijven maakt een bestand aan, maar geen ontbrekende bovenliggende mappen. Maak die eerst aan:
folder = Path("output") / "daily"
folder.mkdir(parents=True, exist_ok=True)
(folder / "report.txt").write_text("Ready\n", encoding="utf-8")
parents=True maakt ontbrekende mappen boven daily aan. exist_ok=True accepteert een map die al bestaat. Het verandert een bestaand gewoon bestand niet in een map.
Belangrijkste punten
Pathvoegt onderdelen samen met/en werkt rechtstreeks metopen().name,stem,suffixenparentgeven toegang tot verschillende onderdelen van een pad.- Een controle op bestaan kan niet garanderen dat later openen lukt.
read_text()leest alle tekst;write_text()vervangt die.- Stel paden samen vanuit
Path(__file__).resolve().parentvoor gegevens ten opzichte van het script. - Gebruik
glob()om overeenkomsten te vinden enmkdir()om ontbrekende mappen aan te maken.
3Lees en schrijf CSV-bestanden
Tabelgegevens hebben meer structuur nodig dan een verzameling regels. Een naam kan een komma bevatten, een veld kan een regeleinde bevatten en een hoeveelheid komt nog steeds als tekst binnen. Je gebruikt de CSV-module om die grenzen te behouden, waarden voor berekeningen om te zetten en resultaten te schrijven die een ander programma kan lezen. Benoemde kolommen maken de verwerking duidelijker, terwijl controles op kopregels en rijindelingen onvolledige gegevens helpen blootleggen.
3.1 CSV-rijen en -velden lezen
Een CSV-bestand slaat een tabel op als tekst. De records zijn rijen en de velden zijn kolomwaarden. Komma’s scheiden gewoonlijk de velden, maar velden tussen aanhalingstekens kunnen komma’s en zelfs regeleinden bevatten. Gebruik de module csv om die waarden bij elkaar te houden.
Laat een lezer aanhalingstekens verwerken
name,quiz1,quiz2
Ana,8,9
Ben,7,6
"Lopez, Maria",10,8
De eerste rij is een kopregel met kolomnamen. De laatste gegevensrij heeft drie velden, geen vier: de komma binnen de aangehaalde naam hoort bij de naam. Een dubbel aanhalingsteken binnen een veld tussen aanhalingstekens wordt tweemaal geschreven. Als je elke regel met split(",") zou splitsen, zou je die regels negeren en de naam in stukken breken.
import csv
with open("grades.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
average = (int(row[1]) + int(row[2])) / 2
print(row[0], average)
De lezer geeft lijsten met strings terug. next(reader) leest de kopregel één keer, waarna de lus de gegevens kan verwerken. Het programma drukt “Ana 8.5”, “Ben 6.5” en “Lopez, Maria 9.0” af. In de eerste gegevensrij levert het omzetten van "8" en "9" samen 17 op; delen door 2 geeft daarna 8,5.
Stem bestandsverwerking en tabelinterpretatie op elkaar af
Open CSV-bestanden met newline="", zodat de module csv zelf regelafsluitingen verwerkt. Dit is van belang wanneer een veld tussen aanhalingstekens een regeleinde bevat. Eén CSV-record kan meerdere fysieke bestandsregels beslaan, dus regels afzonderlijk splitsen is geen vervanging voor een CSV-lezer.
De lezer laat waarden standaard als strings staan. Zonder conversie voegt row[1] + row[2] de strings "8" en "9" samen tot "89". Als je vergeet de kopregel over te slaan, probeert het programma "quiz1" om te zetten en werpt het ValueError op.
Als een bestand leeg kan zijn, leest next(reader, None) een kopregel als die aanwezig is en geeft anders None terug. Een volledig lege CSV-regel wordt []. Sla zulke rijen over met if not row: continue voordat je een index gebruikt. Een niet-lege rij met te weinig velden vereist ook een lengtecontrole; alleen lege rijen overslaan beschermt row[2] niet tegen elk kort record.
Sluit aan bij de opmaak van het bestand
reader = csv.reader(f, delimiter=";", skipinitialspace=True)
Dit kiest puntkomma’s als scheidingstekens en verwijdert spaties direct erna. Kies het scheidingsteken dat het bestand daadwerkelijk gebruikt; een ander scheidingsteken kiezen zet decimale komma’s niet om in decimale punten. float("2,50") werpt nog steeds ValueError op.
Sommige exportbestanden uit spreadsheetprogramma’s beginnen met een UTF-8-bytevolgordemarkering. Als je zo’n bestand leest met encoding="utf-8", kan "\ufeff" aan het begin van het eerste veld blijven staan, waardoor de kop "name" verandert in "\ufeffname". Voor die opmaak verwijdert encoding="utf-8-sig" de markering; hiermee kun je ook UTF-8-bestanden zonder markering lezen.
Belangrijkste punten
- Een CSV-record kan komma’s of regeleinden tussen aanhalingstekens bevatten.
- Gebruik
csv.readerin plaats van gewoon op komma’s te splitsen, zodat aanhalingstekens correct worden verwerkt. - Open CSV-bestanden met
newline=""en een passende tekencodering. - De standaardlezer geeft strings terug; sla een kopregel over vóór numerieke conversie.
- Controleer op lege of korte rijen voordat je velden benadert.
- Kies het juiste scheidingsteken en verwerk een bytevolgordemarkering als die aanwezig is.
3.2 Tabelrijen als CSV schrijven
Een CSV-schrijver zet waarden om in correct gescheiden velden en plaatst ze waar nodig tussen aanhalingstekens. Geef de schrijver rijen als sequenties van waarden en laat hem de leestekens verwerken. Zo voorkom je uitvoer die er goed uitziet totdat een naam of bericht een komma bevat.
Schrijf een kopregel en gegevens
import csv
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["name", "average"])
writer.writerow(["Ana", 8.5])
writer.writerow(["Lopez, Maria", 9.0])
Het bestand bevat de rijen name,average, Ana,8.5 en "Lopez, Maria",9.0. De schrijver zet getallen om in tekst. Hij plaatst de naam met een komma tussen aanhalingstekens en verdubbelt elk dubbel aanhalingsteken binnen een veld tussen aanhalingstekens. None wordt een leeg veld, dus als je het bestand terugleest, krijg je None niet automatisch terug.
writerow() krijgt één rij. writerows() krijgt een sequentie van rijen, zoals [["Ana", 8.5], ["Ben", 6.5]]. Als je "Ana" rechtstreeks aan writerow() doorgeeft, krijgt die drie tekens en ontstaat A,n,a. Gebruik ["Ana"] voor een rij met één veld.
Laat CSV de regelafsluitingen regelen
Gebruik newline="" wanneer je het uitvoerbestand opent. De standaardschrijver sluit records af met "\r\n". Als je ook in tekstmodus regeleindetekens laat vertalen, kan Windows een extra wagenterugloop toevoegen, waardoor in sommige lezers ongewenste lege regels ontstaan. Het argument newline voorkomt die tweede omzetting.
Zet het ene bestand om in het andere
with open("grades.csv", newline="", encoding="utf-8") as src, open("summary.csv", "w", newline="", encoding="utf-8") as dst:
reader = csv.reader(src)
writer = csv.writer(dst)
next(reader)
writer.writerow(["name", "average"])
for row in reader:
average = (int(row[1]) + int(row[2])) / 2
writer.writerow([row[0], round(average, 2)])
Voor de cijferregels “Ana,8,9”, “Ben,7,6” en "Lopez, Maria",10,8 zijn de gemiddelden 8,5, 6,5 en 9,0. De lezer verwijdert de CSV-aanhalingstekens uit de invoerveldwaarde; de schrijver voegt de benodigde aanhalingstekens weer toe aan de uitvoer. round() bepaalt de numerieke waarde die wordt geschreven, maar dwingt geen weergave met twee decimalen af. Gebruik een opmaak zoals f"{average:.2f}" wanneer je precies twee decimalen wilt.
Voeg toe zonder de kopregel te herhalen
Controleer voordat je een bestand opent om tekst toe te voegen of het een kopregel nodig heeft:
from pathlib import Path
p = Path("sales.csv")
needs_header = not p.exists() or p.stat().st_size == 0
with open(p, "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
if needs_header:
writer.writerow(["item", "quantity"])
writer.writerow(["coffee", 4])
Ook een bestaand leeg bestand heeft een kopregel nodig. Als je de kopregel bij elke uitvoering schrijft, komen kolomnamen midden in de gegevens terecht. Dit patroon gaat ervan uit dat één programma het bestand bijwerkt; een controle op bestaan voorkomt niet dat andere programma’s het bestand wijzigen.
Belangrijkste punten
- Geef een sequentie van velden door aan
writerow()en rijen aanwriterows(). - De schrijver zet waarden om en verwerkt aanhalingstekens;
Nonewordt een leeg veld. - Gebruik
newline=""zowel voor CSV-uitvoer als voor CSV-invoer. - Voeg alleen een kopregel toe wanneer het bestand nieuw of leeg is.
3.3 Kolomnamen gebruiken in CSV-code
Code die op positie werkt, zoals row[2], is afhankelijk van de kolomvolgorde. Met een lezer op basis van dictionary’s kun je de waarde die je nodig hebt bij naam noemen. Een dictionary koppelt sleutels aan waarden; hier levert de kopregel de sleutels en levert elk gegevensrecord de bijbehorende waarden.
Lees velden op naam
import csv
with open("inventory.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
rows = list(reader)
Voor de kopregel product,stock,price en de rij notebook,12,2.50 is de eerste dictionary {'product': 'notebook', 'stock': '12', 'price': '2.50'}. reader.fieldnames geeft de namen uit de kopregel. De kopregel wordt automatisch ingelezen; een aanroep van next(reader) zou het eerste gegevensrecord overslaan.
Gebruik row["stock"] om de voorraad te selecteren, ook als de kolommen een andere volgorde krijgen. Zet de waarde om met int() om hoeveelheden te vergelijken. De waarden blijven strings; kolomnamen geven de lezer geen numerieke typen.
Filter en tel op
Stel dat de tabel een voorraad van 12 notitieboeken tegen een prijs van 2,50 bevat, 3 pennen tegen 1,20, 0 nietmachines tegen 7,95 en 25 mappen tegen 0,80.
low = [r for r in rows if int(r["stock"]) < 5]
value = sum(int(r["stock"]) * float(r["price"]) for r in rows)
low bevat de rijen voor de pen en de nietmachine. De waarde is € 53,6: de notitieboeken dragen 30 bij, de pennen 3,6, de nietmachines 0 en de mappen 20. Het filter gebruikt de voorraad, terwijl het totaal zowel de voorraad als de prijs gebruikt.
Maak onderscheid tussen ontbrekende sleutels en ontbrekende waarden
Namen in de kopregel moeten precies overeenkomen. Name en name zijn verschillende sleutels. Een spatie na een komma kan onderdeel worden van een kolomnaam; skipinitialspace=True verwijdert spaties direct na scheidingstekens.
Een kopregel name,quiz1,quiz2 met gegevens Ben,7 levert {'name': 'Ben', 'quiz1': '7', 'quiz2': None} op. De sleutel bestaat, maar de waarde ontbreekt. int(None) werpt TypeError op. Een aanwezig leeg veld is "", en omzetting daarvan werpt ValueError op. Een sleutel die niet in de kopregel voorkomt, veroorzaakt daarentegen KeyError bij het opzoeken.
Bij de gegevens Cara,1,2,3 worden extra velden verzameld als None: ['3']; de benoemde velden bevatten nog steeds "Cara", "1" en "2". Controleer de indeling van een rij wanneer nauwkeurige totalen van elk veld afhangen.
Schrijf geselecteerde kolommen
with open("reorder.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["product", "stock"])
writer.writeheader()
for r in low:
writer.writerow({"product": r["product"], "stock": r["stock"]})
fieldnames bepaalt de uitvoervolgorde, ongeacht de volgorde in de dictionary. Ontbrekende dictionarysleutels worden lege velden. Extra sleutels werpen standaard ValueError op: een voorraaddictionary met price doorgeven aan deze schrijver met twee kolommen mislukt. Maak de kleinere dictionary zoals getoond, of kies extrasaction="ignore" wanneer het weglaten van extra velden de bedoeling is.
Belangrijkste punten
DictReaderleest de kopregel en geeft dictionary’s met stringwaarden terug.- Namen in de kopregel moeten precies overeenkomen met de sleutels waarmee je zoekt.
- Een ontbrekend veld krijgt standaard
None; een aanwezig leeg veld is"". - Extra velden komen standaard onder de sleutel
Noneterecht. DictWriterheeftfieldnamesnodig om de kolomvolgorde te bepalen.- Ontbrekende uitvoersleutels worden lege velden; onverwachte sleutels werpen standaard
ValueErrorop.
4Handel fouten af met try en except
Bestandsnamen kunnen verkeerd zijn, toegang kan worden geweigerd en een numerieke kolom kan een woord bevatten. Een exceptie markeert het punt waarop de normale uitvoering niet kan doorgaan. Je leest foutrapporten, vangt verwachte problemen op en houdt werkzaamheden na succes gescheiden van opruimwerk. Door fouten vervolgens via functieaanroepen te volgen, kun je herstel plaatsen waar een zinvolle keuze mogelijk is, zoals opnieuw proberen te lezen of een afgewezen rij melden.
4.1 Een foutrapport begrijpen
Een exceptie is een object dat tijdens de uitvoering een probleem aangeeft. Het opwerpen ervan onderbreekt de normale uitvoering. Als geen exceptieafhandelaar de exceptie afhandelt, beëindigt Python het programma met een stacktrace, een overzicht van de aanroepen die tot de fout hebben geleid.
Begin onderaan
def average(values):
return sum(values) / len(values)
def report():
scores = []
print(average(scores))
report()
De stacktrace eindigt met ZeroDivisionError: division by zero. Begin daar: het type benoemt het soort probleem en de melding geeft details. Het onderdeel direct daarboven verwijst naar de deling in average(). Eerdere onderdelen tonen de aanroep vanuit report() en de oorspronkelijke aanroep van report(). De lijst is leeg, dus de lengte is 0. De gemelde regel is waar het probleem zichtbaar wordt; de eerdere toekenning van de lege lijst verklaart hoe het ontstond.
Kies het passende type
| Type | Gebruikelijke oorzaak |
|---|---|
ValueError | int("3.5"): een string met een onaanvaardbare waarde |
TypeError | len(5): een bewerking op het verkeerde soort object |
ZeroDivisionError | Delen door nul |
IndexError | Een lijstpositie lezen die niet bestaat |
KeyError | Een ontbrekende dictionarysleutel opzoeken |
NameError | Een niet-gedefinieerde naam gebruiken |
AttributeError | Een object om een attribuut vragen dat het niet heeft |
int("abc") ontvangt een toegestaan invoertype, een string, maar kan die waarde niet als geheel getal interpreteren. "5" + 3 mengt daarentegen typen die niet bij elkaar kunnen worden opgeteld. Een string die cijfers bevat, blijft een string.
Bestandsbewerkingen hebben specifiekere typen: FileNotFoundError voor een ontbrekend pad, PermissionError voor geweigerde toegang en FileExistsError voor het aanmaken van een bestaand bestand met "x". Een map als gewoon bestand openen kan IsADirectoryError opwerpen. Bytes decoderen met een ongeschikte tekencodering kan UnicodeDecodeError opwerpen.
Begrijp de stamboom
Exceptieklassen vormen een hiërarchie. Een exceptieafhandelaar voor een bovenliggende klasse kan de onderliggende klassen opvangen:
OSErroris het bovenliggende type van veelvoorkomende bestandssysteemfouten, waaronderFileNotFoundErrorenPermissionError.LookupErroris het bovenliggende type vanIndexErrorenKeyError.ArithmeticErroris het bovenliggende type vanZeroDivisionError.UnicodeDecodeErrorvalt onderValueError.
Deze takken stammen af van Exception, dat afstamt van BaseException. KeyboardInterrupt en SystemExit stammen daarentegen rechtstreeks af van BaseException. Door dat onderscheid laat except Exception onderbreking door de gebruiker en beëindiging van het programma ongemoeid.
Maak onderscheid tussen syntaxis-, uitvoerings- en logische problemen
Een ontbrekende dubbele punt of een ontbrekend sluitend haakje kan verhinderen dat Python een script ontleedt. De daaruit volgende SyntaxError treedt op voordat het script wordt uitgevoerd, dus een try in datzelfde script kan de fout niet opvangen. Een uitvoeringsexceptie treedt op terwijl geldige code wordt uitgevoerd. Een logische fout levert een verkeerd antwoord op zonder noodzakelijkerwijs een exceptie op te werpen, bijvoorbeeld door een totaal door het verkeerde aantal te delen.
Belangrijkste punten
- Lees eerst het exceptietype en de melding onderaan een stacktrace.
- Gebruik de vermelde aanroepen om de waarde die de fout veroorzaakt terug te volgen naar de oorsprong.
ValueErrorbetreft een onaanvaardbare waarde;TypeErrorbetreft een ongeschikt type.- Een exceptieafhandelaar voor een bovenliggende klasse vangt ook onderliggende exceptieklassen op.
- Syntaxisfouten, uitvoeringsfouten en logische fouten ontstaan op verschillende manieren.
4.2 Een probleem opvangen waar het kan worden afgehandeld
Een try-instructie voert code uit waarbij een fout kan optreden en biedt een herstelpad voor geselecteerde excepties. De exceptieafhandelaar moet passen bij het probleem dat het programma verwacht en waarop het weet te reageren.
Volg het uitvoeringsverloop
while True:
try:
age = int(input("Age: "))
break
except ValueError:
print("Please enter a whole number, like 34.")
print("Next year you will be", age + 1)
Als de gebruiker “twenty” typt, werpt int() ValueError op. Python slaat de rest van de try over, inclusief break, en voert de overeenkomende exceptieafhandelaar uit. Daarna vraagt de lus opnieuw om invoer. Als de gebruiker “34” typt, wordt de try voltooid via break, zodat het programma de lus verlaat en “Next year you will be 35” afdrukt.
Een exceptieafhandelaar hervat de uitvoering niet bij de mislukte instructie. De uitvoering gaat verder na de try-instructie, tenzij de exceptieafhandelaar zelf dat verloop verandert. Als geen exceptieafhandelaar overeenkomt, wordt de exceptie verder naar buiten doorgegeven.
Handel verschillende fouten verschillend af
try:
result = int(a) / int(b)
except ValueError:
print("Both values must be whole numbers.")
except ZeroDivisionError:
print("The second value cannot be 0.")
Een mislukte conversie en een deler die nul is, vereisen verschillende meldingen. Als de reactie hetzelfde moet zijn, groepeer je typen in een tuple: except (ValueError, ZeroDivisionError):. Haakjes werken in heel Python 3. Python 3.14 staat ook een lijst zonder haakjes toe wanneer er geen as-gedeelte is; de tuplevorm blijft in alle versies duidelijk.
Python controleert clausules van boven naar beneden en voert de eerste overeenkomst uit. Zet FileNotFoundError vóór het bovenliggende type OSError als een ontbrekend bestand een speciale reactie vereist. Als je ze omdraait, wordt de specifieke exceptieafhandelaar onbereikbaar.
Gebruik de melding zonder andere programmeerfouten te verbergen
try:
quantity = int(text)
except ValueError as err:
print("Cannot read quantity:", err)
err is het exceptieobject; als je het afdrukt, zie je de melding. type(err).__name__ geeft de klassenaam. Python verwijdert de binding van err wanneer de exceptieafhandelaar eindigt, dus kopieer de melding binnen het blok naar een andere variabele als je die later nodig hebt.
Houd de try klein. Zet latere berekeningen buiten de conversieafhandeling wanneer fouten daarin een andere behandeling vereisen. except Exception: kan programmeerfouten verbergen, zoals een niet-gedefinieerde variabele. Een kale except: is nog breder: die vangt ook KeyboardInterrupt en SystemExit op.
Probeer de bewerking opnieuw, niet een ruwe benadering ervan
Met text.isdigit() controleer je niet alles wat int() accepteert. "-5" en " 34" doorstaan die controle niet, maar worden wel omgezet; "²" doorstaat de controle wel, maar wordt niet door int() omgezet. Door de conversie te proberen en ValueError op te vangen, gebruik je de eigen regels van de conversie.
Doe iets zichtbaars of leg iets vast wanneer je ongeldige gegevens afhandelt. Een lege except ValueError: pass kan het programma laten doorgaan met ontbrekende resultaten zonder vast te leggen wat er misging.
Belangrijkste punten
- Een exceptie slaat de resterende
try-code over en voert de eerste overeenkomende exceptieafhandelaar uit. - Gebruik specifieke typen en zet exceptieafhandelaars voor onderliggende klassen vóór die voor bovenliggende klassen.
- Groepeer typen in een tuple wanneer de herstelactie voor die typen hetzelfde is.
except ... as errgeeft binnen de exceptieafhandelaar toegang tot de melding.- Houd de
trygericht, zodat meldingen de werkelijk mislukte bewerking beschrijven. - Probeer numerieke conversie rechtstreeks wanneer je wilt controleren wat die accepteert.
4.3 Succes, opruimen en fouten tussen functies
Een try-instructie kan de bewerking waarbij een fout kan optreden, het herstel, de werkzaamheden na succes en het opruimen van elkaar scheiden. Een exceptie kan ook een functie verlaten en door de aanroepende code worden afgehandeld.
Geef werkzaamheden na succes een eigen blok
try:
x = 10 / int(text)
except ValueError:
print("not a number")
except ZeroDivisionError:
print("zero")
else:
print("result", x)
finally:
print("done")
Met text = "4" drukt het programma “result 2.5” en “done” af. Met "abc" drukt het “not a number” en “done” af; met "0" drukt het “zero” en “done” af.
else wordt uitgevoerd wanneer de try normaal en zonder exceptie wordt voltooid. Het wordt niet uitgevoerd nadat een exceptieafhandelaar een fout heeft hersteld. Het wordt ook overgeslagen wanneer return, break of continue de try voortijdig verlaat. Fouten die binnen else worden opgeworpen, worden niet opgevangen door de eerdere except-clausules van die instructie, zodat werkzaamheden na succes niet per ongeluk dezelfde exceptieafhandelaars gebruiken als de bewerking waarbij een fout kan optreden.
Laat opruimen bij elke uitgang plaatsvinden
finally wordt uitgevoerd wanneer de uitvoering de instructie verlaat: na succes, na een afgehandelde exceptie en voordat een niet-afgehandelde exceptie verder wordt doorgegeven. Het wordt ook uitgevoerd voordat een op handen zijnde terugkeer wordt voltooid.
def label():
try:
return "from try"
finally:
print("finally ran")
value = label()
print(value)
Dit drukt “finally ran” af en daarna “from try”. De terugkeer wachtte terwijl het opruimen plaatsvond. Voor bestanden regelt with het sluiten al, zodat handmatig sluiten in finally meestal niet nodig is.
Zet geen instructie die het blok verlaat, zoals return, break of continue, in finally. Als je het opruimblok op die manier verlaat, kan een op handen zijnde exceptie worden weggegooid of een retourwaarde worden overschreven. Python 3.14 en later geven voor dit patroon een SyntaxWarning. Gebruik het opruimblok alleen om op te ruimen.
Volg een exceptie naar de aanroepende code
def read_scores(path):
with open(path, encoding="utf-8") as f:
return [int(line) for line in f]
try:
scores = read_scores("scores.txt")
except FileNotFoundError:
print("The score file is missing.")
Als het openen mislukt, heeft read_scores() geen exceptieafhandelaar, dus wordt FileNotFoundError doorgegeven aan de aanroep binnen de buitenste try. De aanroepende code handelt de exceptie af en drukt de melding af. Als een regel geen geheel getal is, volgt een ValueError dezelfde route, maar de exceptieafhandelaar voor een ontbrekend bestand komt daar niet mee overeen.
Kies het niveau dat zinvol kan reageren
Een leesfunctie weet mogelijk hoe ze gegevens moet ophalen, maar niet of een ontbrekend bestand moet leiden tot opnieuw proberen, een taak overslaan of gecontroleerd stoppen. Door de exceptie de aanroepende code te laten bereiken die met de gebruiker communiceert, blijft die keuze daar. Als je de exceptie te vroeg opvangt en een lege lijst teruggeeft, kan het verschil tussen een leeg bestand en een mislukte leesactie verborgen blijven.
Belangrijkste punten
elsewordt alleen uitgevoerd nadat de inhoud van detrynormaal is voltooid.finallywordt uitgevoerd voordat de uitvoering het blok verlaat, ook bij een terugkeer of een niet-afgehandelde exceptie.- Een exceptie in
elsevalt buiten de voorafgaande exceptieafhandelaars in die instructie. - Vermijd manieren om
finallyte verlaten die op handen zijnde fouten of retourwaarden kunnen weggooien. - Niet-afgehandelde excepties worden via aanroepen doorgegeven aan een overeenkomende buitenliggende exceptieafhandelaar.
4.4 Herstellen van bestands- en rijfouten
Een programma handelt een fout gecontroleerd af wanneer het beheerst en bruikbaar op een probleem reageert. Het kan opnieuw vragen, een overgeslagen rij melden of stoppen met een duidelijke melding. Kies die reactie op basis van waarvoor het resultaat wordt gebruikt.
Probeer een ontbrekend bestand opnieuw
while True:
name = input("File name: ").strip()
try:
with open(name, encoding="utf-8") as f:
text = f.read()
except FileNotFoundError:
print(f"No file named '{name}'. Please try again.")
else:
break
print(len(text.splitlines()), "lines")
Een mislukte opening slaat de toekenning over en bereikt de exceptieafhandelaar. De lus vraagt opnieuw om invoer. Een geslaagde leesactie bereikt else, verlaat de lus en laat text beschikbaar voor de eindtelling. with sluit het bestand op beide manieren waarop een eenmaal betreden blok kan worden verlaten.
Gebruik voor verschillende bestandsproblemen eerst FileNotFoundError, dan PermissionError en daarna een algemene OSError-afhandelaar als andere bestandssysteemfouten een reactie vereisen. De specifieke clausules moeten eerst komen. Ongeldige bytes decoderen is een ander probleem; een melding over een ontbrekend pad zou dat niet beschrijven.
Handel elke gegevensrij afzonderlijk af
Stel dat voor een snel verkoopoverzicht de CSV-rijen na de kopregel coffee,4, tea,two, muffin,3, cookie, en juice,5 zijn.
import csv
total = 0
skipped = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
next(reader, None)
for row in reader:
try:
if len(row) != 2:
raise ValueError("expected two fields")
quantity = int(row[1])
except ValueError as err:
skipped += 1
print(f"sales.csv, ending line {reader.line_num}: {err}")
else:
total += quantity
print("Total:", total, "Skipped:", skipped)
De geldige hoeveelheden tellen op tot 12. Het woord “two” en de lege hoeveelheid worden afgewezen, dus het aantal overgeslagen rijen is 2. De rijcontrole maakt van een onverwacht aantal velden ook een gemelde gegevensfout voordat een index wordt gebruikt. Door try binnen de lus te plaatsen, kan het volgende record worden verwerkt nadat er één mislukt; als je de lus binnen één try plaatst, verlaat je de lus bij de eerste fout.
Meld locaties nauwkeurig
Voor de vijf records van één regel eindigen de ongeldige waarden op bestandsregels 3 en 5. enumerate(reader, start=2) zou hier met die regelnummers overeenkomen, maar door een regeleinde tussen aanhalingstekens kan een CSV-record meer dan één regel beslaan. reader.line_num geeft aan hoeveel fysieke regels de lezer heeft verwerkt. Door dit de eindregel te noemen, blijven meldingen nauwkeurig voor records die meerdere regels beslaan.
Bepaal of een gedeeltelijk resultaat aanvaardbaar is
Een snelle verkennende telling kan gemelde overgeslagen rijen toestaan. Een financieel totaal of een cijfertotaal kan elk record vereisen: stop en vraag om gecorrigeerde gegevens in plaats van een gedeeltelijk totaal als volledig te presenteren. Noem het bestand, de locatie en het probleem zodat het kan worden opgelost.
Na import sys schrijft sys.exit("Could not open sales.csv") de melding naar de foutuitvoer en stopt het programma met afsluitcode 1. Dit werpt SystemExit op, wat except Exception niet opvangt. Houd exceptieafhandelaars specifiek, zodat een niet-gerelateerde programmeerfout niet ten onrechte als een bestandsprobleem wordt aangeduid.
Belangrijkste punten
- Kies opnieuw proberen, overslaan of stoppen op basis van de taak.
- Plaats foutherstel per rij binnen de lus om na een ongeldige rij door te gaan.
- Meld overgeslagen records en geef gedeeltelijke resultaten duidelijk aan.
- CSV-recordnummers kunnen verschillen van fysieke regelnummers.
sys.exit(message)beëindigt het programma met een foutmelding en afsluitcode 1.- Gebruik specifieke exceptieafhandelaars zodat de melding bij het werkelijke probleem past.
5Werp zelf excepties op
Functies hebben een duidelijke manier nodig om invoer te melden die ze niet kunnen verwerken. Een exceptie opwerpen voorkomt dat een mislukte bewerking een misleidend resultaat oplevert en laat de aanroepende code een reactie kiezen. Je kiest betekenisvolle typen en meldingen, geeft een bestaande fout door en behoudt de oorzaak wanneer je die omzet. Een kort patroon met een zelfgedefinieerde klasse geeft een programma een eigen fouttype wanneer aanroepende code het ene probleem van het andere moet kunnen onderscheiden.
5.1 Invoer afwijzen met raise
Een functie moet een signaal geven wanneer ze geen geldig resultaat kan opleveren. raise werpt op dat punt een exceptie op, zodat het ongeldige pad niet kan doorgaan alsof de bewerking is geslaagd.
Controleer vóór het rekenen
def withdraw(balance, amount):
if amount <= 0:
raise ValueError(f"amount must be positive, got {amount}")
if amount > balance:
raise ValueError(f"amount {amount} is more than the balance {balance}")
return balance - amount
withdraw(100, 30) geeft 70 terug. withdraw(100, 150) werpt een fout op over het saldo; withdraw(100, -5) werpt een fout op over een niet-positief bedrag. Geen van beide mislukte aanroepen bereikt de aftrekking.
Een opgeworpen exceptie volgt dezelfde afhandelingsregels als een ingebouwde fout. Als een overeenkomende exceptieafhandelaar binnen de functie de exceptie opvangt, kan de uitvoering daar doorgaan. Anders verlaat de exceptie de functie en bereikt ze de aanroepende code. Als geen exceptieafhandelaar wordt gevonden, toont Python een stacktrace.
Laat de aanroepende code de reactie kiezen
balance = 100
amount = 150
try:
balance = withdraw(balance, amount)
except ValueError as err:
print(f"Cannot withdraw: {err}")
De functie meldt waarom ze geen geld kan opnemen. De aanroepende code besluit een melding te tonen. Omdat de functieaanroep mislukt voordat een waarde wordt teruggegeven, vervangt de toekenning het oude saldo niet door een resultaat. Andere aanroepende code zou om een lager bedrag kunnen vragen of een transactie kunnen annuleren zonder de functie te wijzigen.
Als de functie in plaats daarvan een waarschuwing afdrukt en None teruggeeft, kan de aanroepende code een ongeldige waarde meenemen naar een latere berekening. Door een exceptie op te werpen blijft de fout verbonden met de oorzaak en krijgt de aanroepende code een afzonderlijk foutpad.
Kies een betekenisvol type
| Probleem | Geschikt type |
|---|---|
| Juiste soort invoer, onaanvaardbare waarde | ValueError |
| Verkeerde soort object voor de bewerking | TypeError |
Een negatief numeriek bedrag heeft een onaanvaardbare waarde. Een lijst die wordt opgegeven waar een getal nodig is, heeft een ongeschikt type. Het exceptietype maakt deel uit van het gedrag van de functie: aanroepende code gebruikt het om exceptieafhandelaars te kiezen. Kies een type niet alleen omdat het bekend is.
Schrijf een bruikbare melding
Een melding moet benoemen wat werd verwacht en wat werd ontvangen. f"age must be between 0 and 130, got {age}" wijst op een oplossing. Een melding als “fout” geeft geen bruikbare details. Laat de melding over de mislukte bewerking gaan; code die met de gebruiker communiceert, kan de bredere context toevoegen.
raise ValueError("amount must be positive") maakt een exceptie met een melding. raise ValueError is ook geldig en maakt er een zonder melding. Een gewone string is geen exceptie: raise "error" werpt TypeError op omdat opgeworpen objecten moeten afstammen van BaseException.
Belangrijkste punten
- Werp een exceptie op waar een functie niet correct kan doorgaan.
- Gebruik
ValueErrorvoor een onaanvaardbare waarde enTypeErrorvoor een ongeschikt type. - Neem de verwachte invoer en de ontvangen waarde op in een behulpzame melding.
- Laat de aanroepende code beslissen hoe op de mislukte bewerking wordt gereageerd.
5.2 Excepties doorgeven en benoemen
Soms merkt een functie een fout op, maar kan ze die niet volledig afhandelen. Ze moet mogelijk dezelfde fout doorgeven, omzetten in een bruikbaardere fout of een specifiek programmaprobleem een eigen exceptietype geven.
Werp de huidige fout opnieuw op
def read_text(path):
try:
with open(path, encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
print(f"Missing: {path}")
raise
De kale raise binnen de exceptieafhandelaar werpt de huidige exceptie opnieuw op. Alleen een melding afdrukken zou de exceptieafhandelaar beëindigen en de functie None laten teruggeven; opnieuw opwerpen maakt de mislukte leesactie zichtbaar voor de aanroepende code. Een kale raise heeft een actieve exceptie nodig om opnieuw op te werpen.
Zet om met behoud van de oorzaak
def read_price(row):
try:
text = row["price"]
except KeyError as err:
raise ValueError("row has no 'price' column") from err
return float(text)
Een ontbrekende sleutel wordt een ValueError met een melding over de rij. from err legt de oorspronkelijke KeyError vast als directe oorzaak. De stacktrace toont de oorspronkelijke fout, het verband ertussen en de nieuwe fout. De aanroepende code kan het omgezette type afhandelen terwijl de onderliggende oorzaak voor het debuggen beschikbaar blijft.
Deze exceptieafhandelaar is beperkt tot het opzoeken. Een aanwezige waarde zoals "free" mislukt later bij float(text) met een eigen ValueError; die wordt niet ten onrechte als een ontbrekende kolom gemeld.
Definieer een afzonderlijk type
class InsufficientFundsError(ValueError):
pass
Dit patroon maakt een zelfgedefinieerde exceptieklasse. De naam eindigt volgens afspraak op Error. De naam tussen haakjes is het bovenliggende type, dus deze klasse is een soort ValueError.
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(
f"balance {balance}, requested {amount}"
)
return balance - amount
try:
withdraw(100, 150)
except InsufficientFundsError as err:
print("Not enough money:", err)
Het programma drukt “Not enough money: balance 100, requested 150” af. Aanroepende code kan onvoldoende saldo onderscheiden van een andere ongeldige waarde. Als een ValueError-afhandelaar vóór deze specifieke exceptieafhandelaar zou staan, zou het bovenliggende type de exceptie als eerste opvangen.
Kies het bovenliggende type voor de gewenste afhandeling
Als je afleidt van ValueError, kunnen zowel een specifieke exceptieafhandelaar als een bredere afhandelaar voor waardefouten het zelfgedefinieerde type opvangen. Rechtstreeks afleiden van Exception maakt een aparte tak voor gewone fouten, zodat except ValueError de exceptie niet zou opvangen. Een zelfgedefinieerd type is handig wanneer aanroepende code een afzonderlijke reactie nodig heeft; een duidelijk ingebouwd type en een duidelijke melding zijn voldoende wanneer dat niet zo is.
Belangrijkste punten
- Een kale
raisein een exceptieafhandelaar geeft de huidige exceptie door. raise NewError(...) from errlegt de oorspronkelijke fout vast als directe oorzaak.- Een zelfgedefinieerde exceptie geeft aanroepende code een afzonderlijk probleemtype.
- De bovenliggende klasse bepaalt welke bredere exceptieafhandelaars de zelfgedefinieerde fout kunnen opvangen.
- Plaats een specifieke exceptieafhandelaar voor een zelfgedefinieerd type vóór de afhandelaar voor het bovenliggende type.
Bestanden en excepties in Python: voorbeelden
1Zet een tekstbestand om in een gefilterd rapport
13 stappen
- 1IntroductieLees, beslis, sla op
Een ondersteuningslogbestand bevat één gebeurtenis per regel. Je wilt een nieuw bestand met alleen de gebeurtenissen die aandacht vereisen. Die taak combineert lezen, stringcontroles en schrijven.
Volg eerst hoe een bestand tekst levert. Bouw daarna het filter in kleine stappen, houd de invoer gescheiden van de uitvoer en laat
withbeide bestanden sluiten wanneer de verwerking eindigt. - 2UitlegEen bestand levert strings
Stel dat
events.txt"INFO Ready\nERROR Queue full\n"bevat. Als je het opent, ontstaat een bestandsobject, geen kopie van de tekst.f.readline()geeft"INFO Ready\n"terug. Een tweede aanroep geeft"ERROR Queue full\n"terug. Een derde geeft""terug omdat het bestand is uitgelezen. Het regeleindeteken blijft aan een teruggegeven regel vastzitten; ook numerieke tekst blijft tekst totdat die expliciet wordt omgezet. - 3UitdagingKies een leesmethode
Een logbestand kan veel groter zijn dan het beschikbare geheugen. Je hoeft elke regel maar één keer te bekijken. Hoe moet je het lezen en waarom?
---reveal---
Doorloop het open bestand rechtstreeks met
for line in f:. Dit levert één regel tegelijk zonder eerst een string of lijst van het hele bestand nodig te hebben. Een aanroep vanread()ofreadlines()zou de resterende inhoud in het geheugen laden. - 4VoorbeeldHoud het lezen binnen het blok
with open("events.txt", encoding="utf-8") as f: first = f.readline() print(first.rstrip("\n"))Het lezen gebeurt terwijl het bestand open is. Als je het ingesprongen blok verlaat, sluit het bestand; de latere afdruk gebruikt de opgeslagen string. Daarom kan een bewerking op
firstdaarna plaatsvinden, terwijl een nieuwef.readline()dat niet kan. - 5UitdagingVoorspel het opruimen na een fout
Stel dat binnen dat bestandsblok
int("oops")ValueErroropwerpt. De omringende code heeft geen exceptieafhandelaar. Blijft het bestand open en verbergtwithde fout?---reveal---
Het bestand sluit wanneer de uitvoering het betreden blok verlaat. De fout wordt nog steeds doorgegeven en levert een stacktrace op als niets haar opvangt. Automatisch opruimen beschermt de levensduur van het bestand; voor herstel zou een
except-afhandelaar nodig zijn. - 6UitlegKies wat er met de uitvoer gebeurt
Het gefilterde rapport moet een ouder rapport vervangen, dus open een ander uitvoerpad met
"w". Die modus maakt een bestaand bestand onmiddellijk leeg.Gebruik
"a"voor een activiteitengeschiedenis die eerdere uitvoeringen bewaart. Als een bestaand rapport tegen vervanging moet worden beschermd, gebruik je"x"en handel jeFileExistsErroraf. Om een bestand aan te maken moeten de bovenliggende mappen nog steeds bestaan. - 7VoorbeeldSchrijf precies één regel
Om een geselecteerde regel te schrijven, behoud je de oorspronkelijke regelafsluiting:
dst.write(line)Als je de regel daarentegen met
strip()hebt opgeschoond, voeg je de afsluiting weer toe:dst.write(cleaned + "\n")write()voegt geen scheidingsteken toe.print(cleaned, file=dst)is een andere manier om een regeleindeteken toe te voegen, terwijlwritelines()nog steeds verwacht dat de opgegeven strings de benodigde afsluitingen bevatten. - 8UitdagingVoorspel twee uitvoeringen
Er is aanvankelijk geen bestand en een programma wordt tweemaal uitgevoerd. Elke uitvoering opent
"runs.txt"in toevoegmodus en roeptf.write("OK")aan. Welke tekst wordt opgeslagen?---reveal---
Het bestand bevat
"OKOK". De toevoegmodus behoudt de eerste uitvoering, maar noch de modus nochwrite()voegt een regeleindeteken toe. Als je in plaats daarvan"OK\n"zou schrijven, ontstaat één regel per uitvoering. Openen met"w"zou alleen de laatste"OK"achterlaten. - 9VoorbeeldSchoon op vóór het selecteren
Ons logbestand gebruikt het eerste woord als niveau. Begin elke iteratie met:
cleaned = line.strip() if not cleaned: continue level = cleaned.split(maxsplit=1)[0]De controle op een lege regel voorkomt dat een lege lijst met een index wordt benaderd. Door de oorspronkelijke
lineapart te bewaren, kan de uitvoer de oorspronkelijke witruimte behouden. Alleen de opgeschoonde kopie wordt gebruikt om het niveau te bepalen. - 10UitdagingControleer het juiste deel
Het logbestand bevat “INFO ERROR counter reset” en “ERROR Queue full”. Welke niveaucontrole slaat alleen het tweede record op?
---reveal---
Controleer
level == "ERROR"nadat je het eerste woord hebt opgehaald. Overal naar"ERROR"zoeken zou ook het informatieve record opslaan omdat het woord in het bericht voorkomt. De indeling vertelt je waar je de categorie vindt die je selecteert. - 11VoorbeeldStel het filter samen
count = 0 with open("events.txt", encoding="utf-8") as src, open("urgent.txt", "w", encoding="utf-8") as dst: for line in src: cleaned = line.strip() if not cleaned: continue if cleaned.split(maxsplit=1)[0] == "ERROR": dst.write(line) count += 1 print(count, "saved")De teller verandert alleen wanneer een record wordt geschreven. Beide bestanden sluiten voordat de telling wordt afgedrukt.
- 12UitdagingOnderzoek een verloren bron
Iemand verandert de uitvoernaam in
"events.txt"en behoudt"w". Waarom loopt het filter nu het risico niets op te slaan, hoewel de bron eerst werd geopend?---reveal---
De tweede opening maakt hetzelfde onderliggende bestand leeg voordat de lus het leest. Het eerste bestandsobject heeft geen aparte kopie van de oude tekst opgeslagen. Herstel een ander uitvoerpad zodat de omzetting haar invoer niet bij het openen kan wissen.
- 13SamenvattingVolg een bestandstaak vóór uitvoering
Volg bij een bestandsomzetting vier beslissingen: waar de invoer vandaan komt, hoeveel tekst tegelijk wordt gelezen, wat een record selecteert en wat het openen van de uitvoer met bestaande gegevens doet.
Controleer daarna de grenzen van het blok. Bestandsbewerkingen hebben open bestandsobjecten nodig; opgeslagen strings, lijsten en totalen kunnen worden gebruikt nadat die zijn gesloten.
2Vind projectgegevens vanuit elke startmap
9 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieVind de beginmap
- 2VoorbeeldVolg een start
- 3UitdagingVerander de startmap
- 4TipControleer voordat je het pad verandert
- 5VoorbeeldStel samen vanuit het script
- 6UitlegBereid een doel voor
- 7UitdagingBekijk een naam en vind overeenkomsten
- 8UitdagingControleer een voorgestelde oplossing
- 9SamenvattingMaak onderscheid tussen locatie en beschikbaarheid
3Lees een tabel en schrijf een rapport met benoemde kolommen
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieBehoud de structuur van de tabel
- 2VoorbeeldLees één record met aanhalingstekens
- 3VoorbeeldOpen en converteer
- 4UitdagingHerken een korte rij
- 5VoorbeeldSchrijf waarden als velden
- 6UitdagingHoud één veld bij elkaar
- 7UitlegGebruik de kopregel als sleutels
- 8VoorbeeldFilter op voorraad
- 9UitdagingMaak onderscheid tussen ontbrekend en leeg
- 10VoorbeeldExporteer geselecteerde kolommen
- 11UitdagingVoeg een latere reeks toe
- 12TipKies passende scheidingstekens en tekencoderingen
- 13SamenvattingControleer zowel structuur als betekenis
4Volg een fout van een ongeldige rij naar een bruikbare reactie
15 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieKies waarvan herstel mogelijk is
- 2VoorbeeldBegin met het exceptietype
- 3UitdagingHerken een andere fout
- 4VoorbeeldVang alleen de verwachte conversiefout op
- 5UitdagingZet verwante exceptieafhandelaars in volgorde
- 6UitlegGeef succes en opruimen afzonderlijke taken
- 7UitdagingVolg een fout zonder overeenkomst
- 8VerbandLaat de aanroepende code beslissen
- 9VoorbeeldHoud herstel binnen de recordlus
- 10VoorbeeldVolg drie records
- 11UitdagingVerander de grens van de lus
- 12TipBenoem de locatie correct
- 13UitdagingKies een volledig resultaat
- 14VoorbeeldStop met een foutstatus
- 15SamenvattingPlaats elke reactie op het juiste niveau
5Ontwerp het foutgedrag van een functie
10 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieGeef fouten een duidelijk pad
- 2VoorbeeldWijs ongeldige aanvragen af
- 3UitdagingVolg een mislukte toekenning
- 4UitlegKies het type dat bij het probleem past
- 5VoorbeeldGeef een specifiek tekort een naam
- 6UitdagingHoud de specifieke reactie bereikbaar
- 7VoorbeeldReageer en geef de fout door
- 8VoorbeeldZet een onderliggende fout om
- 9UitdagingKies de juiste relatie
- 10SamenvattingHoud de fout betekenisvol voor de aanroepende code
Bestanden en excepties in Python: oefenvragen
Set 1: Bestanden en herstelpaden doorlopen10 Oefenvragen
Vraag 1 van 10
f.writelines(["red", "blue\n"]) en daarna nogmaals geopend in toevoegmodus om "green\n" te schrijven. Welke tekst bevat het?Toon antwoordVerberg antwoord
writelines() voegt geen scheidingstekens toe, dus schrijft de eerste bewerking "redblue\n". De toevoegmodus behoudt daarna die tekst en voegt "green\n" toe. Het ontbrekende regeleindeteken na “red” wordt niet door de methodenaam aangevuld en de toevoegmodus vervangt eerdere uitvoer niet.Vraag 2 van 10
Een bestand bevat alleen “bad”. Wat wordt afgedrukt?
try:
with open("one.txt", encoding="utf-8") as f:
value = int(f.readline())
except ValueError:
print(f.closed)
Toon antwoordVerberg antwoord
with-blok, dus sluit het verlaten van dat blok het bestand voordat de buitenste exceptieafhandelaar wordt uitgevoerd. De afgedrukte waarde is True. De exceptieafhandelaar zorgt voor herstel; with zorgt voor opruimen en hervat de mislukte conversie niet.Vraag 3 van 10
results en results/daily ontbreken. Wat moet worden uitgevoerd voordat je schrijft met Path("results/daily/run.txt").write_text("ok", encoding="utf-8")?Toon antwoordVerberg antwoord
parents=True zodat ook de ontbrekende bovenliggende map wordt aangemaakt. exist_ok=True staat ook latere uitvoeringen toe wanneer de map al bestaat. Zonder parents=True mislukt het aanmaken van daily omdat results ontbreekt; schrijven maakt geen van beide mappen aan.Vraag 4 van 10
not p.exists(). Het pad bestaat, maar heeft nul bytes. Welke voorwaarde geeft ook dit bestand de benodigde kopregel?Toon antwoordVerberg antwoord
or. De groottecontrole vangt het geval van nul bytes op dat een controle op bestaan alleen mist. Met and zou een bestaand leeg bestand worden gemist en zou mogelijk een ontbrekend pad worden onderzocht.Vraag 5 van 10
DictReader heeft de kopregel name,first,second en leest Inez,5. Welke waarde wordt opgeslagen onder "second" en wat gebeurt er wanneer die aan int() wordt doorgegeven?Toon antwoordVerberg antwoord
None, dus bestaat de sleutel uit de kopregel, maar werpt int(None) TypeError op. Een aanwezig leeg veld zou "" bevatten en ValueError opwerpen. Een kopregel definieert de sleutel ook wanneer dit record te weinig waarden heeft.Vraag 6 van 10
{"east": 4}["west"] op?Toon antwoordVerberg antwoord
"west", dus werpt het opzoeken KeyError op. IndexError betreft een ongeldige positie in een sequentie, zoals een lijstindex. De dictionary en de string zijn geldige objecten; het is de gevraagde sleutel die ontbreekt.Vraag 7 van 10
Wat ontvangt de aanroepende code en wat wordt eerst afgedrukt?
def choose():
try:
return 11
finally:
print("leaving")
x = choose()
Toon antwoordVerberg antwoord
finally “leaving” afdrukt voordat de functie haar terugkeer voltooit. Afdrukken tijdens het opruimen vervangt die wachtende retourwaarde niet. Een return binnen finally zou dit gedrag veranderen, maar dit blok bevat alleen print().Vraag 8 van 10
try/except ValueError voor de conversie staan?Toon antwoordVerberg antwoord
Vraag 9 van 10
class LimitError(ValueError): pass wordt een LimitError opgeworpen. Wat gebeurt er als except ValueError: vóór except LimitError: staat?Toon antwoordVerberg antwoord
LimitError erft van ValueError, dus komt de exceptieafhandelaar voor het bovenliggende type als eerste overeen en wordt alleen die uitgevoerd. Zelfgedefinieerde typen volgen dezelfde regel van de eerste overeenkomst als ingebouwde typen. Zet de zelfgedefinieerde exceptieafhandelaar eerst wanneer zijn reactie moet verschillen van die op andere waardefouten.Vraag 10 van 10
parts = line.split(maxsplit=2) in. Records moeten een datum, niveau en bericht hebben, maar sommige bevatten alleen een datum. Welke controle moet voorafgaan aan parts[1] en parts[2]?Toon antwoordVerberg antwoord
maxsplit=2 levert er maximaal drie op, dus controleert len(parts) == 3 de vereiste indeling. Lege regels overslaan beschermt niet tegen een niet-leeg record met één veld. Ook het aantal tekens stelt het aantal velden niet vast.Set 2: Bestanden lezen en kleine programma’s volgen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
"oak\npine". Wat geeft f.readline() terug direct nadat het bestand is geopend om te lezen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Het blok wordt normaal voltooid. Wat wordt afgedrukt?
with open("memo.txt", encoding="utf-8") as f:
text = f.read()
print(f.closed)
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
/work/lab. Hij voert python tools/count.py uit, dat "inputs/list.txt" opent. Welke absolute locatie vraagt dat relatieve pad op?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
p = Path("exports/week/report.csv") de waarde van p.stem?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
csv.reader gelezen uit het record "River, West",6,8?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
writer.writerow("Leo") op met de standaardkomma als scheidingsteken?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
"many". Welke exceptie werpt int(row["quantity"]) op?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Wat wordt afgedrukt?
def read_count(text):
return 12 / int(text)
try:
result = read_count("0")
print("read")
except ValueError:
print("bad text")
except ZeroDivisionError:
print("zero")
print("end")
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
-2?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Methoden kiezen en verwachte fouten afhandelen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
"09:10 INFO ERROR count reset" en "09:12 ERROR Network down". Het niveau is het tweede veld, gescheiden door witruimte. Welke voorwaarde selecteert alleen records met het foutniveau?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
"12\n15\n". Welk paar ontstaat door first = f.read() gevolgd door second = f.read() op één zojuist geopende lezer?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
"C:\new\tasks.txt" in Windows het bedoelde bestand mogelijk niet aanduiden?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
city,visitors en Mesa,24. Na reader = csv.DictReader(f) roept het programma eenmaal next(reader) aan en begint daarna een lus. Waarom ontbreekt Mesa in die lus?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
label;count, maar de standaard-CSV-lezer geeft ["label;count"] terug. Welke instelling van de lezer past bij dit bestand?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Wat wordt afgedrukt?
try:
value = 18 / int("0")
except ZeroDivisionError:
print("zero")
else:
print("success")
finally:
print("closed")
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
try treedt een FileNotFoundError op. De eerste exceptieafhandelaar is except OSError: print("file problem") en de tweede is except FileNotFoundError: print("missing"). Wat wordt afgedrukt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
except ValueError:-blok dezelfde actieve exceptie door aan de aanroepende code?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Wat wordt afgedrukt?
def reserve(n):
if n <= 0:
raise ValueError("positive count required")
return n * 2
result = 7
try:
result = reserve(0)
except ValueError:
print(result)
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Onvolledige gegevens en misleidende exceptieafhandelaars onderzoeken10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
f.readline() terug aan het einde van een bestand?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
data.txt bevat drie records. Een programma opent het met "r", opent daarna hetzelfde pad met "w" en begint pas dan te lezen via het eerste bestandsobject. Waarom loop je hierdoor het risico de invoer te verliezen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
p.exists() geeft True terug, maar het bestand wordt verwijderd vóór open(p, encoding="utf-8"). Wat heeft een robuust programma bij die opening nog steeds nodig?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
data/menu.txt naast zijn eigen locatie lezen, ongeacht de startmap. Welke expressie stelt dat pad in het script samen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
encoding="utf-8" is de eerste sleutel uit de kopregel "\ufeffcode". Welke wijziging bij het openen verwijdert de markering met behoud van UTF-8-tekst?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
{"title": "Map", "stock": "4", "cost": "3.50"}. Een standaard ingestelde DictWriter heeft fieldnames=["title", "stock"]. Wat gebeurt er wanneer die de hele rij ongewijzigd schrijft?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
ValueError van int(text) op. Die exceptieafhandelaar drukt missing_name af, dat nooit is gedefinieerd. Wat gebeurt er met de nieuwe NameError?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
"North op fysieke regel 2 en eindigt het met Hall",7 op regel 3. Welke locatie geeft reader.line_num na het lezen ervan?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
None terug bij een negatieve grootte. De aanroepende code vermenigvuldigt het resultaat onmiddellijk met 4. Waarom zou ValueError opwerpen tijdens de validatie dit foutpad verbeteren?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
KeyError als err voert een exceptieafhandelaar raise ValueError("missing unit column") from err uit. Wat ontvangt de aanroepende code en welke oorzaak blijft behouden?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 5: Bestandsverwerking combineren met betrouwbaar foutgedrag10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
with open("source.txt", encoding="utf-8") as src, open("new.txt", "x", encoding="utf-8") as dst:. De bron wordt geopend, maar new.txt bestaat al. Wat gebeurt er met src en de inhoud van het blok?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
"10:00 INFO ERROR resolved", "10:01 ERROR Disk slow" en "10:02 ERROR Disk full". Het tweede veld is het niveau. Hoeveel records worden opgeslagen na filteren op het foutniveau?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
/srv/course, voert tools/read.py uit en opent "../shared/items.txt". Welk pad vraagt het op?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
["Vale, East", None, 3]. Welk record ontstaat, zonder de laatste regelafsluiting mee te tellen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Wat wordt afgedrukt voordat de fout wordt doorgegeven?
try:
n = int("2")
except ValueError:
print("bad input")
else:
print("ready")
result = 9 / 0
finally:
print("cleanup")
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
int() accepteert, inclusief spaties aan het begin en een teken voor het getal. Waarom probeer je int(text) in try in plaats van eerst text.isdigit() te vereisen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
sys.exit("Required file unavailable") uit binnen code die onder except Exception: valt. Wat gebeurt er?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
total = 0 en skipped = 0. Een binnenste exceptieafhandelaar slaat een rij over als die minder dan twee velden heeft of als int(row[1]) mislukt. Hij telt geldig geconverteerde waarden bij het totaal op. Welk eindpaar wordt gemeld voor de rijen ["lamp", "8"], ["desk"], ["chair", "bad"] en ["shelf", "5"]?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
class ImportDataError(Exception): pass vangt aanroepende code alleen ValueError op. Wat gebeurt er wanneer de hulpfunctie ImportDataError opwerpt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
aanroepende code
absoluut pad
/ op Unixachtige systemen of de wortel van een station in Windows./Users/maya/data/notes.txt is niet afhankelijk van de huidige werkmap.accumulator
errors begint bij 0 en wordt met 1 verhoogd telkens wanneer de lus een record met het foutniveau vindt.afkappen
"w" vernietigt de oude records, ook als het programma nooit een schrijfaanroep bereikt.afsluitcode
sys.exit("Missing input") drukt de melding af naar de foutuitvoer en eindigt met afsluitcode 1.AttributeError
"hi".push("!") werpt AttributeError op omdat een Pythonstring geen methode met de naam push heeft.B
bestandsextensie
suffix van een pad.Path("data/sales.csv") is ".csv", die een programma kan gebruiken bij het selecteren van tabelbestanden.bestandsmodus
open() dat de toegestane toegang bepaalt en aangeeft hoe bij het openen met bestaande inhoud op het pad wordt omgegaan."a" om eerdere meldingen te bewaren, terwijl een nieuw rapport "w" kan gebruiken om ze te vervangen.bestandsnaam zonder laatste extensie
Path("logs/run.txt") is de bestandsnaam zonder laatste extensie "run", terwijl de volledige laatste naam "run.txt" is.bestandsobject
open() teruggeeft en dat een programma methoden biedt om een geopend bestand te lezen of te schrijven.with open("notes.txt", encoding="utf-8") as f: verwijst de naam f naar het bestandsobject.bestandspositie
f.read() de resterende inhoud heeft gelezen, geeft een tweede leesactie een lege string terug.binaire modus
"rb" duidt invoer van bytes aan, terwijl tekstinvoer een modus zoals "r" gebruikt.bovenliggende exceptieklasse
bovenliggende map
parent van een pad selecteert die omvattende locatie.Path("reports/2026/sales.csv") is de bovenliggende map het pad reports/2026.buffer
bytevolgordemarkering
encoding="utf-8-sig" verwijdert de markering aan het begin zodat de eerste kolomnaam overeenkomt met de bedoelde naam.C
contextbeheerder
with-blok regelt, zoals toegang openen en opruimen.CSV
"Lopez, Maria",10,8 heeft drie velden omdat de eerste komma binnen een naam tussen aanhalingstekens staat.CSV-schrijver
D
DictReader
name,score kan een rij met row["score"] worden benaderd, ook als de kolommen een andere volgorde krijgen.DictWriter
fieldnames=["product", "stock"] exporteert die kolommen wanneer passende dictionary’s worden doorgegeven.doorgifte van excepties
E
else-clausule
exceptie
int("many") werpt een exceptie op voordat de volgende instructie in dat blok wordt uitgevoerd.exceptieafhandelaar
exceptiehiërarchie
excepties koppelen
raise ... from err een eerdere fout vast als directe oorzaak van een nieuwe exceptie.exclusief aanmaken
FileExistsError op als daar al een bestand bestaat."x" voorkomt dat een nieuw gegenereerd rapport ongemerkt een rapport op hetzelfde pad vervangt.extra veld
None.F
fieldnames
writeheader() op een DictWriter drukt de namen af in de ingestelde volgorde van fieldnames.FileExistsError
"x" werpt FileExistsError op in plaats van de inhoud te vervangen.FileNotFoundError
finally-clausule
foutherstel per record
foutmelding
fysiek regelnummer
line_num van de lezer geeft de laatst gelezen regel aan voor een record dat twee regels beslaat.G
gecontroleerde foutafhandeling
gedelegeerde exceptieafhandeling
gesloten bestand
with-blok waarin een bestand als f is geopend, is geëindigd, is f.closed gelijk aan True en werpt f.read() een ValueError op over toegang tot een gesloten bestand.globpatroon
* overeenkomt met wisselende tekst binnen de geselecteerde map.Path("logs").glob("*.txt") vindt overeenkomende paden naar tekstbestanden; door ze te sorteren krijg je een voorspelbare verwerkingsvolgorde.H
huidige werkmap
python tools/report.py uitvoeren vanuit de hoofdmap van het project verplaatst de uitvoering op zichzelf niet naar de map tools.I
IndexError
IsADirectoryError
K
KeyboardInterrupt
except: kan Ctrl+C opvangen, terwijl except Exception: de onderbreking laat doorgeven.KeyError
row["name"] mislukt wanneer de kopregel van de tabel in plaats daarvan de sleutel "Name" heeft aangemaakt.kopregel
product,stock,price benoemt kolommen en mag niet als gegevens worden doorgegeven aan een conversie naar gehele getallen.L
logische fout
M
mappen aanmaken
mkdir(parents=True) kan ook ontbrekende mappen boven de gevraagde map aanmaken.output/daily aan voordat je het rapport daarin schrijft, want een nieuw uitvoerbestand openen maakt geen mappen aan.N
naambinding van een exceptie
as een naam aan een opgevangen foutobject, zodat het type of de melding ervan binnen die exceptieafhandelaar kan worden bekeken.except ValueError as err: toont het afdrukken van err de melding; de binding wordt daarna verwijderd.NameError
O
ontbrekend veld
None.name,score heeft de rij Ana een ontbrekende score; Ana, bevat daarentegen een lege scorestring.opnieuw opwerpen
raise, zodat lokaal kan worden gereageerd zonder de fout als opgelost te behandelen.P
pad
data/notes.txt duidt een tekstbestand aan in de map data onder de huidige werkmap.Path-object
Path("data") / "scores.txt" stelt een locatie samen die open() rechtstreeks kan accepteren.PermissionError
R
raise-instructie
raise ValueError("amount must be positive").record
recordafsluiting
"\r\n".newline="" kan de schrijver zijn eigen afsluitingen toevoegen zonder een tweede omzetting.regeleindeteken
"\n" in een Pythonstring, markeert een regeleinde; de laatste regel van een bestand hoeft geen regelafsluiting te hebben."\n" voegt nog een regeleindeteken toe, tenzij de afsluiting van de afdruk wordt gewijzigd.regelfilter
"ERROR".relatief pad
project/scripts begint, verwijst ../data/notes.txt naar de naastgelegen gegevensmap van het project.ruwe string
r-voorvoegsel zodat backslashes als letterlijke tekens behouden blijven in plaats van als gewone escapesequenties te worden geïnterpreteerd.r"C:\new\table.txt" behoudt de scheidingstekens die anders escapesequenties voor een regeleinde en een tab zouden beginnen.S
scheidingsteken
delimiter=";" nodig zodat een lezer name;score in twee velden splitst.specifieke exceptieafhandelaar
stacktrace
SystemExit
sys.exit() opgeworpen buiten de gewone tak van Exception.sys.exit("Missing data") werpt SystemExit op met een melding en een foutstatus die een gewone Exception-afhandelaar niet opvangt.T
tekencodering
tekstbestand
toevoegmodus
"a" gebruikt voor uitvoeringsmeldingen, blijven eerdere uitvoeringen bewaard, maar de melding heeft nog steeds een eigen regeleindeteken nodig.try-blok
TypeError
"5" en 3 optellen werpt TypeError op omdat het optellen van strings geen geheel getal als tweede operand accepteert.U
UnicodeDecodeError
encoding="utf-8".UTF-8
encoding="utf-8" wanneer je een als UTF-8 opgeslagen tekstbestand opent, zodat letters met accenten correct worden gedecodeerd.V
validatie
ValueError
"3.5" is een toegestaan invoertype voor int(), maar is geen string met een geheel getal en werpt ValueError op.veld
velden tussen aanhalingstekens plaatsen
"River, West", terwijl gewoon op komma’s splitsen die naam zou opdelen.W
with-instructie
with-blok is geopend, sluit ook wanneer het omzetten van een regel binnen het blok een fout opwerpt.witruimte aan de randen verwijderen
line.strip() wordt een regel met alleen spaties en een regeleindeteken een lege string.writerow
writer.writerow(["Ana", 8.5]) voor een record met twee velden, geen vooraf samengevoegde string.writerows
writerows() worden doorgegeven om meerdere records in één aanroep op te slaan.Z
zelfgedefinieerde exceptie
ZeroDivisionError
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.