2.25. Virheiden käsittely¶
Useimmat ajonaikaiset ongelmat Pythonissa ilmenevät poikkeuksina – nimettynä, jäsenneltynä tapana raportoida, että jokin meni pieleen. ValueError, TypeError, KeyError, OSError ja MemoryError ovat kaikki esimerkkejä; jokainen on luokka, ja sellaisen nostaminen pysäyttää nykyisen kutsun ja etsii käsittelijää ympäröivästä koodista.
2.25.1. try / except¶
Kääri koodilohko try -lauseeseen napataksesi minkä tahansa sen nostaman poikkeuksen:
try:
n = int(input_text)
except ValueError:
n = 0
Jos int(...) -muunnos epäonnistuu, suoritus siirtyy except -lohkoon sen sijaan, että virhe etenisi edelleen. Jos input_text oli kelvollinen kokonaislukumerkkijono, except -lohko ohitetaan.
Yhdellä try -lohkolla voi olla useita except -lohkoja, joista kukin nappaa erityyppisen virheen:
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
Python sovittaa järjestyksessä; ensimmäinen, jonka poikkeusluokka sopii, käsittelee ongelman. Exception -luokan (lähes kaiken perusluokka) nappaaminen käsittelee minkä tahansa virheen; varaa se ohjelman uloimmalle kerrokselle, jossa vaihtoehtona on kaatuminen.
Varoitus
Paljas except: (ei luokkaa avainsanan jälkeen) nappaa myös KeyboardInterrupt -poikkeuksen – poikkeuksen, jonka IDE lähettää, kun painat sen stop-painiketta keskeyttääksesi käynnissä olevan skriptin. Paljaaseen except: pass -lauseeseen käärityn silmukan nielee keskeytyksen ja jatkaa toimintaansa, jättäen skriptin pysäyttämiseen ainoaksi keinoksi virtakatkon.
Suosi except Exception: -muotoa paljaan except: -muodon sijaan, kun sinun on aidosti napattava laajasti. KeyboardInterrupt periytyy BaseException -luokasta, ei Exception -luokasta, joten except Exception: jättää stop-painikkeen toimintakuntoon.
2.25.1.1. Poikkeuksen tarkastelu¶
Lukeaksesi poikkeukseen liitetyn viestin, nimeä se as -avainsanalla:
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
as -lauseella sidottu muuttuja on voimassa vain except -lohkon sisällä.
2.25.2. else ja finally¶
try -lohkolla on kaksi valinnaista lisäystä.
else suoritetaan vain, kun try päättyi nostamatta poikkeusta:
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
”Mitä tehdä, kun se onnistui” -koodin sijoittaminen else -lohkoon pitää try -lohkon suppeana – vain rivi, joka saattaa epäonnistua, kuuluu try -lohkoon.
finally suoritetaan lopussa kaikissa tapauksissa – riippumatta siitä, onnistuiko try, nostiko se poikkeuksen joka käsiteltiin, vai nostiko se poikkeuksen joka on etenemässä:
try:
do_work()
finally:
cleanup()
finally suoritetaan aina. else suoritetaan vain poikkeuksettomalla polulla.¶
Useimmissa varaa/vapauta-kaavoissa suosi kontekstinhallintaa try / finally -parin sijaan – resurssi hallinnoi itse omaa siivoamistaan.
2.25.3. Yleisiä sisäänrakennettuja poikkeuksia¶
Lyhyt lista poikkeuksista, joihin törmäät usein:
ValueError– oikea tyyppi, väärä arvo (bytes([300])– 300 on oikea tyyppi, mutta on kelvollisen tavualueen 0..255 ulkopuolella).TypeError– kokonaan väärä tyyppi (len(42)).IndexError– indeksi sekvenssin lopun ohi.AttributeError– olemattoman attribuutin käyttö ("abc".foo).OSError– tiedostojärjestelmän tai I/O:n vika.MemoryError– keko loppui. Muistirajoitteisessa ajoympäristössä tämä voi tapahtua normaalin toiminnan aikana – ei vain poikkeustapauksissa.