2.25. Gestionarea erorilor¶
Majoritatea problemelor de execuție din Python apar sub formă de excepții – un mod denumit și structurat de a raporta că ceva nu a mers bine. ValueError, TypeError, KeyError, OSError, MemoryError sunt toate exemple; fiecare este o clasă, iar generarea (raising) uneia oprește apelul curent și caută un gestionar în codul înconjurător.
2.25.1. try / except¶
Încadrează un bloc de cod în try pentru a captura orice excepție pe care o generează:
try:
n = int(input_text)
except ValueError:
n = 0
Dacă conversia int(...) eșuează, controlul sare la blocul except în loc să propage eroarea mai departe. Dacă input_text era un șir reprezentând un întreg valid, blocul except este sărit.
Un singur try poate avea mai multe blocuri except, fiecare capturând un tip diferit de eroare:
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
Python le potrivește în ordine; primul a cărui clasă de excepție se potrivește tratează problema. Capturarea Exception (clasa de bază pentru aproape orice) tratează orice eroare; rezervă aceasta pentru stratul cel mai exterior al unui program, acolo unde alternativa este o blocare.
Atenționare
Un except: simplu (fără clasă după cuvântul-cheie) capturează și KeyboardInterrupt – excepția pe care o trimite IDE-ul atunci când apeși butonul stop pentru a întrerupe un script în execuție. O buclă încadrată într-un except: pass simplu va înghiți întreruperea și va continua să ruleze, neavând nicio altă cale de a opri scriptul decât oprirea și repornirea alimentării.
Preferă except Exception: în locul lui except: simplu atunci când chiar ai nevoie să capturezi pe scară largă. KeyboardInterrupt moștenește din BaseException, nu din Exception, așa că except Exception: lasă butonul stop să funcționeze.
2.25.1.1. Inspectarea excepției¶
Pentru a citi mesajul atașat unei excepții, denumește-o cu as:
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
Variabila legată prin as este validă doar în interiorul blocului except.
2.25.2. else și finally¶
Un bloc try are două opțiuni suplimentare.
else rulează doar când try s-a finalizat fără a genera o excepție:
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
Plasarea „ce să faci când a reușit” în else menține blocul try restrâns – în try ar trebui să se afle doar linia care ar putea eșua.
finally rulează la final indiferent de situație – fie că try a reușit, a generat o excepție care a fost tratată, sau a generat o excepție pe cale să se propage:
try:
do_work()
finally:
cleanup()
finally rulează întotdeauna. else rulează doar pe calea fără excepție.¶
Pentru majoritatea tiparelor de alocare/eliberare, preferă un gestionar de context în locul unei perechi try / finally – resursa însăși își gestionează propria curățare.
2.25.3. Excepții încorporate comune¶
O scurtă listă a excepțiilor pe care le vei întâlni frecvent:
ValueError– tip corect, valoare greșită (bytes([300])– 300 este tipul corect, dar se află în afara intervalului valid de octeți 0..255).TypeError– tip complet greșit (len(42)).IndexError– index dincolo de sfârșitul unei secvențe.AttributeError– accesarea unui atribut care nu există ("abc".foo).OSError– o eroare de sistem de fișiere sau de I/O.MemoryError– a rămas fără heap. Pe un mediu de execuție cu memorie limitată, acest lucru se poate întâmpla în timpul funcționării normale – nu doar în cazuri patologice.