U Pythonu, hvatanje izuzetaka pomaže da se smanji broj situacija kada se programi neočekivano prekidaju. Na taj način, vaš kod postaje pouzdaniji i korisnicima se pruža bolje iskustvo. U ovom tekstu ćemo istražiti kako uhvatiti više izuzetaka unutar jednog `try/except` bloka u Pythonu.
Šta su izuzeci u Pythonu?
U Pythonu, izuzeci služe kao mehanizam komunikacije između različitih delova programa. Ovaj mehanizam omogućava jednom delu sistema da prijavi da je naišao na kritičnu grešku sa kojom ne može da se nosi.
Kada se takva situacija desi, dolazi do izuzetka. Drugi deo programa, koji je pripremljen za rukovanje takvom greškom, hvata izuzetak i preduzima odgovarajuće korake.
Ukoliko se izuzeci ne obrade, program će se zaustaviti sa greškom. Stoga, pravilno rukovanje izuzecima sprečava pad programa i poboljšava njegovu pouzdanost.
Za potrebe ovog članka, pretpostavićemo da ste već upoznati sa osnovama podizanja i rukovanja izuzecima, što je obrađeno u članku Uvod u Python `try/except`.
Važnost rukovanja višestrukim izuzecima u Pythonu
- Smanjuje se ponavljanje koda, jer se nekoliko izuzetaka obrađuje u istom bloku. Ovo doprinosi čitljivosti, olakšava modifikaciju i uklanjanje koda.
- Takođe, omogućava pisanje efikasnijeg koda, budući da se tip greške proverava samo jednom, umesto više puta.
Rukovanje višestrukim izuzecima
Hvatanje višestrukih izuzetaka podrazumeva situaciju u kojoj se više različitih izuzetaka obrađuje pomoću jednog `except` bloka. U Pythonu je moguće obrađivati različite izuzetke u odvojenim `except` blokovima.
Kada je potrebno postupati sa izuzecima na sličan način, moguće je sve ih obraditi jednim blokom. Za to je neophodno uhvatiti više izuzetaka istovremeno. U ovom odeljku ćemo detaljnije objasniti kako se to radi uz pomoć primera.
#1. Hvatanje različitih izuzetaka u odvojenim blokovima
Zamislite program koji uzima dve vrednosti i deli ih. U ovom programu očekujemo da se mogu pojaviti različiti tipovi izuzetaka kada korisnik unese neispravne vrednosti. Konkretno, želimo da obradimo `ValueError` i `ZeroDivisionError`.
`ValueError` će se pojaviti kada korisnik unese vrednost koja se ne može pretvoriti u ceo broj. `ZeroDivisionError` će se pojaviti kada je drugi broj nula. U oba slučaja, želimo da prikažemo poruku o grešci koja glasi: „Uneli ste nevažeću vrednost“.
Da bismo postigli gore navedeno, možemo napisati sledeći kod:
try: dividend = int(input('Unesite prvi broj: ')) divisor = int(input('Unesite drugi broj: ')) quotient = dividend / divisor print(quotient) except ValueError as e: print("Uneli ste nevažeću vrednost") except ZeroDivisionError as e: print("Uneli ste nevažeću vrednost") except Exception as e: print("Došlo je do greške")
Ako pokrenemo gornji kod i unesemo tekst koji ne može da se prevede u broj, dobićemo sledeći rezultat:
A ako drugi broj unesemo kao 0, ovo bi bio rezultat:
Kod radi kako se očekuje, ali primetite da se sa `ValueError` i `ZeroDivisionError` postupa na sličan način. Postoji dosta ponavljanja koda između dva `except` bloka. Ovo nije idealno, jer kršimo DRY princip u programiranju. DRY princip kaže „Ne ponavljaj se“.
Dakle, umesto da pišemo kod odvojeno, možemo kombinovati dva bloka u jedan blok koji hvata više izuzetaka. Ako to uradimo, izbegavamo ponavljanje.
#2. Hvatanje više izuzetaka u jednom `except` bloku
Da bismo uhvatili više izuzetaka, koristimo tuple koji sadrži sve greške koje želimo da obradimo. Evo primera gde hvatamo i `ValueError` i `ZeroDivisionError` u jednom `except` bloku:
try: dividend = int(input('Unesite prvi broj: ')) divisor = int(input('Unesite drugi broj: ')) quotient = dividend / divisor print(quotient) except (ValueError, ZeroDivisionError) as e: print("Uneli ste nevažeću vrednost") except Exception as e: print("Došlo je do greške")
Ovo je mnogo bolja implementacija od prethodnog koda. Suština je u rukovanju višestrukim izuzecima. Kod iznad radi na isti način kao i ranije. Ako testirate koristeći prethodne primere, trebalo bi da radi kao i pre:
#3. Identifikovanje koji izuzetak je uhvaćen
Gornji kod izvršava prvi `except` blok kada je uhvaćen ili `ValueError` ili `ZeroDivisionError`. U nekim situacijama, možda ćete želeti da se neki kod izvrši za obe greške, a neki drugi kod samo za jednu, a ne za drugu grešku.
U tom slučaju, prvo morate da utvrdite koji je izuzetak uhvaćen, a zatim izvršiti odgovarajući kod.
Da biste identifikovali koji je izuzetak uhvaćen, možete koristiti `if/else` blok unutar `except` bloka. Na primer:
try: dividend = int(input('Unesite prvi broj: ')) divisor = int(input('Unesite drugi broj: ')) quotient = dividend / divisor print(quotient) except (ValueError, ZeroDivisionError) as e: print("Uneli ste nevažeću vrednost") if isinstance(e, ValueError): print('Greška u vrednosti') else: print('Greška deljenja nulom') except Exception as e: print("Došlo je do greške")
U ovom bloku, pored štampanja generičke poruke o grešci i za `ValueError` i za `ZeroDivisionError`, proveravamo tačno koju vrstu greške smo uhvatili i štampamo dodatnu poruku. Ako ponovo testiramo kod, trebalo bi da vidimo neke dodatne poruke koje su specifične za uhvaćeni izuzetak.
Kada je korisno rukovati višestrukim izuzecima?
U opštem slučaju, rukovanje višestrukim izuzecima je idealno kada želite da izvršite isti kod za slične izuzetke koji se mogu pokrenuti. Ovo uključuje sledeće:
- Mrežni zahtevi koji nisu uspeli iz različitih razloga. Bez obzira na to, možda ćete želeti da obavestite korisnika da server nije dostupan.
- Neuspešne veze sa bazom podataka, koje proizvode više grešaka. Iako ove greške mogu biti različite, vaše rukovanje može biti isto.
- U/I operacije sa fajlovima takođe mogu generisati greške kojima se može rukovati na sličan način, kao što su greške sa dozvolama i greške usled nedostatka prostora na disku.
Zaključak
Ovaj članak je obradio kako kombinovati više `except` blokova u jedan hvatanjem više izuzetaka istovremeno. Ovo pomaže da vaš kod postane čitljiviji i lakši za održavanje. Sledeće, možda želite da pročitate ovaj članak o Python početničkim projektima koje bi trebalo da probate.