python try except python handling exception with examples
Acest tutorial explică Exception Handling in Python folosind blocul Try Except cu ajutorul exemplelor de programare:
Două tipuri de erori pot determina oprirea bruscă a unui program Python, adică Erori de sintaxă , și Excepții . În acest tutorial, vom discuta al doilea tip de eroare (excepții) în cadrul mai multor subiecte importante.
Vom beneficia foarte mult de gestionarea excepțiilor din aplicația noastră, cum ar fi:
- Crearea unei aplicații robuste.
- Crearea unui cod curat și fără erori.
=> Vizitați aici pentru seria exclusivă de instruire Python
Ce veți învăța:
- Python Încercați cu excepția
- Excepții comune Python
- Concluzie
Python Încercați cu excepția
O veste bună este că Python are un număr bun de excepții încorporate pentru a prinde erori în codul nostru. De asemenea, ne oferă posibilitatea de a crea excepții personalizate atunci când niciuna dintre excepțiile încorporate nu se potrivește nevoilor noastre.
Ce este o excepție
Deci, ce este o excepție în Python? Ei bine, în termeni simpli, ori de câte ori interpretul Python încearcă să execute cod nevalid, ridică o excepție și, în cazurile în care o astfel de excepție nu este gestionată, aceasta perturbă fluxul normal al instrucțiunilor programului și imprimă un traceback.
Să creăm un cod nevalid și să vedem cum va răspunde interpretul Python.
Deschideți un shell Python și rulați următorul cod.
>>> 50/0
Aceasta este una dintre cele mai frecvente erori în programare. Codul de mai sus încearcă să împartă numărul cincizeci de 0 (zero). Interpretul Python vede acest lucru ca pe o operație nevalidă și crește un ZeroDivisionError , întrerupe programul și imprimă un traceback.
Putem vedea clar asta ZeroDivisionError este excepția care a fost ridicată. Într-adevăr, este propriul mod Python de a ne spune că nu este bine să împărțiți un număr la zero. Deși în alte limbi cum ar fi JavaScript, aceasta nu este o eroare; iar python interzice strict această practică.
De asemenea, este important să știm că acesta este doar un obiect de excepție și că Python are multe astfel de obiecte încorporate. Verificați acest oficial Python documentație pentru a vedea toate excepțiile încorporate Python.
Înțelegerea Traceback
Înainte de a intra în gestionarea excepțiilor, cred că va ajuta să înțelegem ce se va întâmpla exact dacă excepțiile nu sunt gestionate și cum Python face tot posibilul să ne informeze despre eroarea noastră.
Ori de câte ori Python întâlnește o eroare, aceasta ridică o excepție. Dacă această excepție nu este gestionată, atunci produce unele informații numite Traceback. Deci, ce informații conține acest traceback?
Contine:
- Mesajul de eroare care ne spune ce excepție a fost ridicată și ce s-a întâmplat înainte ca această excepție să fie ridicată.
- Diversele numere de linie ale codului care au provocat această eroare. O eroare poate fi cauzată de o secvență de apeluri funcționale numite a stivă de apeluri despre care vom discuta mai târziu aici.
Deși este puțin confuz, promitem că următorul exemplu va aduce mai multă lumină înțelegerii noastre.
Reamintim traceback-ul care a fost tipărit din împărțirea 50 la 0 de mai sus, putem vedea că traceback conține următoarele informații:
- Fișier „”: Aceasta ne spune că acest cod a fost rulat de la un terminal de consolă.
- linia 1: Aceasta ne spune că eroarea a apărut în acest număr de linie.
- ZeroDivisionError: împărțire prin zero: Ne spune ce excepție a fost ridicată și ce a cauzat-o.
Să încercăm un alt exemplu și poate să vedem cum a stivă de apeluri se pare ca. Deschideți un editor, introduceți codul de mai jos și salvați ca tracebackExp .py
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 compute = numb/div # 6 print(compute) # 7 if __name__ == '__main__': # 9 numb = 5 # 10 stack1(numb) # 11
Deschideți un terminal în directorul unde se găsește acest fișier și rulați.
python tracebackExp.py
Veți vedea următorul trackback:
Traseul de mai sus poate părea confuz, dar într-adevăr nu este. Pythonistas a venit cu cel mai bun mod de a citi traceback, care este din de jos în sus . Deci, să folosim această înțelepciune pentru a încerca să înțelegem ce are de oferit acest traseu.
- În partea de jos, obținem excepția care a fost ridicată și de ce a fost ridicată.
- Mergând în sus, obținem numele fișierului tracebackExp .py unde a apărut această eroare, calculul care a cauzat această eroare calculează = numb / div, funcția stack2 și numărul de legătură linia 6 unde a fost efectuat acest calcul.
- Mergând în sus, vedem că funcția noastră stack2 a fost apelată în funcția stack1 în linia numărul 3.
- Trecând la cel mai de sus, vedem că funcția stack1 a fost numită în linia numărul 11.< modul > ne spune că fișierul este executat.
Excepții comune Python
Biblioteca Python definește o mulțime de excepții încorporate. Puteți verifica documentația Python sau puteți apela dispozitivul încorporat local () funcționează după cum urmează:
>>> dir(locals()('__builtins__'))
Nu vom încerca să abordăm toate aceste excepții, dar vom vedea câteva excepții comune pe care probabil le veți întâlni.
# 1) TypeError
Se ridică atunci când o operație sau o funcție este aplicată unui obiect de tip inadecvat.
Exemplul 1
Luați în considerare programul de mai jos. Acesta ia un dividend și divizor, apoi calculează și imprimă rezultatul împărțirii dividendului la divizor.
def compute_division(): dividend = int(input('Enter the dividend: ')) # cast string to int divisor = input('Enter the divisor: ') # no casting # Compute division result = dividend/divisor # print result print('The result of {}/{} is: {}'.format(dividend, divisor, result)) if __name__ == '__main__': result = compute_division()
Solicităm valoarea dividendului și a divizorului de la utilizator, dar uităm să aruncăm valoarea șirului divizorului într-un număr întreg. Deci, ajungem cu tipul dividendului fiind întreg ( int ) și tipul divizorului fiind șir ( str ). Apoi obținem Eroare de scris deoarece operatorul de divizie (/) nu operează pe șiruri.
S-ar putea să vă intereseze să știți că, spre deosebire de Python, Javascript are Type Coercion care convertește practic unul dintre tipurile de operand într-o valoare echivalentă cu tipul celuilalt operand atunci când operandii sunt de diferite tipuri.
# 2) ValueError
Aceasta se ridică atunci când o operație sau o funcție primește un argument care are tipul corect, dar o valoare inadecvată.
Exemplul 2
Luați în considerare programul nostru în Exemplul 1 de mai sus.
Dacă utilizatorul introduce o valoare alfanumerică pentru dividend, cum ar fi „3a”, atunci programul nostru va ridica excepția ValueError. Acest lucru se datorează faptului că, deși Python int () metoda acceptă orice număr sau șir și returnează un obiect întreg, valoarea șirului nu trebuie să conțină litere sau orice valoare nenumerică.
# 3) AttributeError
Această excepție este ridicată în timpul atribuirii sau referințării unui atribut care nu există.
Exemplul 3
Luați în considerare programul de mai jos. Acesta ia un număr și își calculează rădăcina pătrată folosind Modul matematic Python
import math # import math library to gain access to its code def compute_square_root(number): # compute the square root using the math library result = math.sqr(number) return result if __name__ == '__main__': # get input to compute from user number = int(input('Compute Square root of: ')) # call function to compute square root
Când un utilizator introduce un număr, programul nostru încearcă să utilizeze o funcție din modulul matematic pentru a calcula rădăcina pătrată, dar tocmai aici am făcut o eroare. În loc de sqrt, am tastat greșit sqr care nu există în modulul matematic.
Deci, am încercat să facem referire la un atribut sqr care nu există și a condus la ridicarea excepției AttributeError. Majoritatea dintre noi facem acest tip de greșeală foarte mult. Deci, nu ești singur.
Gestionarea excepțiilor cu Încercați cu excepția
Ca programator, un lucru pe care majoritatea dintre noi ne vom petrece timpul este să scriem un cod robust care să fie rezistent. Cod care nu se rupe din cauza unor erori. În Python, putem realiza acest lucru prin includerea declarațiilor noastre în interiorul unui încerca - cu exceptia afirmație.
Instrucțiune Python Try-Except
Instrucțiunea try-except are următoarea structură:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Să includem codul în tracebackExp .py în interiorul unei declarații try-except.
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 try: # 6 compute = numb/div # 7 print(compute) # 8 except ZeroDivisionError as zde: # 9 print(zde) # 10 if __name__ == '__main__': # 12 numb = 5 # 13 stack1(numb) # 14 print('program continuous') # 15
Rularea acestui cod va produce ieșirea
Așa funcționează declarația try-except. Python execută codul din blocul try linia 7-8 . Dacă nu se găsește niciun cod nevalid, atunci codul din blocul cu excepția linia 10 este omis și execuția continuă.
Dar, dacă este găsit un cod nevalid, atunci executarea se oprește imediat în blocul try și verifică dacă excepția ridicată se potrivește cu cea pe care am furnizat-o în declarația except linia 9 . Dacă se potrivește, atunci blocul cu excepția este executat și continuă. Dacă nu, programul se va întrerupe.
Blocul de încercare conține de obicei codul care poate ridica o excepție, în timp ce blocul de excepție prinde și gestionează excepția.
Gestionarea mai multor excepții cu excepția
Putem gestiona mai multe excepții fie cu un singur „excepție”, fie cu „excepții” multiple. Totul depinde de modul în care doriți să gestionați fiecare excepție.
# 1) Gestionarea mai multor excepții cu o singură excepție
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Această metodă este utilizată atunci când suspectăm că codul nostru poate ridica excepții diferite și dorim să facem aceeași acțiune în fiecare caz. Deci, dacă interpretul Python găsește o potrivire, atunci codul scris în blocul cu excepția se va executa.
Să luăm în considerare exemplul de cod Python de mai jos
def get_fraction(value, idx): arr = (4,5,2,0) # a list of numbers idx_value = arr(idx) # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 3 # call function in a try-except statement. try: result = get_fraction(value, idx) print('Fraction is ', result) except (IndexError, ZeroDivisionError) as ex: print(ex)
Avem două posibile excepții care ar putea fi ridicate aici, ZeroDivisionError și IndexError . Dacă se ridică oricare dintre aceste excepții, atunci blocul cu excepția va fi executat.
În codul de mai sus, idx = 3, deci idx_ valoare devine 0 și valoare / idx_ valoare va ridica ZeroDivisionError
# 2) Gestionarea mai multor excepții cu mai multe excepții
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Dacă am dori mai degrabă să gestionăm fiecare excepție separat, atunci așa o puteți face.
Luați în considerare exemplul de cod Python de mai jos
def get_fraction(value, idx): arr = (4,5,2,0) # a list of numbers idx_value = arr(idx) # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 5 # call function in a try-excepts statement. try: result = get_fraction(value, idx) print('Fraction is ', result) except IndexError: print('idx of {} is out of range'.format(idx)) except ZeroDivisionError: print('arr({}) is 0. Hence, can't divide by zero'.format(idx)) except Exception as ex: print(ex) print('Not sure what happened so not safe to continue, app will be interrupted') raise ex
Observăm aici că Excepția a fost folosită în ultima afirmație cu excepția. Acest lucru se datorează faptului că obiectul de excepție Exception se potrivește cu orice excepție. Din acest motiv, ar trebui să fie întotdeauna ultimul, deoarece Python va opri verificarea altor manipulatori de excepție odată ce unul se potrivește.
În codul de mai sus, idx = 5 , prin urmare arr (idx) va ridica IndexError deoarece idx este mai mare decât lungimea listei arr
De asemenea, nu sunteți sigur ce excepție a fost ridicată de aplicația dvs. nu este niciodată sigură pentru a continua executarea. De aceea, avem tipul Excepție pentru a surprinde orice excepție neprevăzută. Apoi, informăm utilizatorul și întrerupem aplicația ridicând aceeași excepție.
Încercați Declarația Else
Aceasta este o caracteristică opțională de gestionare a excepțiilor și vă permite să adăugați cod pe care doriți să îl executați atunci când nu au apărut erori. Dacă apare o eroare, acest bloc de blocare nu va rula.
Luați în considerare exemplul de cod Python de mai jos, deschideți editorul și salvați codul ca elseTry.py
def fraction_of_one(divisor): value = 1/divisor # if divisor is zero, ZeroDivisionError will be raised return value if __name__ == '__main__': while True: try: # Get input from the user. # if input is not a valid argument for int(), ValueError will be raised divisor = int(input('Enter a divisor: ')) # call our function to compute the fraction value = fraction_of_one(divisor) except (ValueError, ZeroDivisionError): print('Input can't be zero and should be a valid literal for int(). Please, try again!') else: print('Value: ', value) break
Primim date de la utilizator și le folosim pentru a împărți 1. Avem două posibile excepții aici, o intrare de utilizator nevalidă care va provoca ValueError și a zero (0) care va provoca ZeroDivisionError . Declarația cu excepția noastră gestionează aceste erori.
Acum, dorim să imprimăm valoarea lui valoare . Blocul nostru altceva se asigură că este tipărit numai dacă blocul nostru de încercare se execută fără o eroare. Acest lucru este important deoarece, dacă apare o eroare în blocul nostru de încercare, valoare va fi nedefinit. Deci, accesarea acestuia va ridica o altă eroare.
Rulați codul de mai sus cu Python elseTry.py
Ieșirea de mai sus arată că, pentru prima intrare, am tastat 0 și a apăsat ENTER. Deoarece divizorul nostru a primit 0, 1 / divizorul a crescut zeroDivisionError . A doua noastră intrare a fost k, care nu este validă pentru int (), de unde și excepția ValueError este crescut.
Dar ultima noastră informație a fost 9, ceea ce este valid și, ca rezultat, am obținut valoarea „ valoare ”Tipărit ca 0.1111111111111111
Încercați Declarația În cele din urmă
Aceasta este, de asemenea, un caracteristică opțională de gestionare a excepțiilor și va rula întotdeauna indiferent de ce se întâmplă în handlerele de excepție.
Acesta este:
- Dacă apare sau nu o excepție
- Chiar dacă o „returnare” este apelată în celelalte blocuri.
- Chiar dacă scriptul este închis în celelalte blocuri
Deci, dacă avem un cod pe care vrem să-l rulăm în toate situațiile, în sfârșit blocarea este tipul nostru. Acest bloc este utilizat mai ales pentru curățări precum închiderea fișierelor.
Luați în considerare exemplul de cod Python de mai jos
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: print('Cleaning...') openFile.close() if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
Acest cod încearcă să deschidă și să citească fișierul text.txt în directorul său curent. Dacă fișierul există, atunci programul nostru va imprima prima linie a fișierului, apoi blocul nostru final va rula și va închide fișierul.
Să presupunem că avem un fișier numit text.txt în directorul în care se află acest fișier de program și conține Hello. Dacă rulăm programul, vom avea rezultatul
Acest exemplu a fost ales în mod intenționat, deoarece am vrut să abordăm o mică problemă care poate apărea la închiderea fișierelor din blocul final.
Dacă fișierul nu există, excepția FileNotFoundError va fi mărită și variabila deschide fișierul nu va fi definit și nu va fi un obiect de fișier. Prin urmare, încercarea de a o închide în blocul final va genera o excepție UnboundLocalError care este o subclasă a NameError .
Aceasta spune practic că încercăm să facem referire la variabilă deschide fișierul înainte de a fi atribuit.
Un mic truc aici este să folosiți handler-uri de excepție în interiorul blocului final.
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: try: print('Cleaning...') openFile.close() except: # catches all exceptions pass # Ignore this error because we don't care. if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
Dacă blocul nostru de încercare creează FileNotFoundError, atunci vom avea următoarea ieșire
Creșteți excepția
O veste bună despre excepțiile Python este că le putem ridica în mod intenționat. Excepțiile sunt ridicate cu declarație de ridicare .
Instrucțiunea raise are următoarea sintaxă:
raise (ExceptionName((*args: Object)))
Deschideți un terminal și ridicați orice obiect de excepție din Excepții încorporate Python. De exemplu, dacă ridicăm ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Vom obține traceback-ul:
Deci, de ce este important să ridici excepții?
- Când lucrați cu excepții personalizate.
- În timpul controalelor de sănătate.
Clase de excepții personalizate
O excepție personalizată este cea pe care o creați pentru a gestiona erorile specifice nevoilor dvs. Trucul este că definim o clasă care derivă din obiect Excepție , apoi folosim declarația raise pentru a crește clasa noastră de excepție.
Să presupunem că dorim să verificăm datele introduse de utilizator și să ne asigurăm că valoarea de intrare nu este negativă (verificarea sănătății). Desigur, am putea ridica excepția Python ValueError, dar ne va plăcea să personalizăm eroarea oferindu-i un nume specific și auto-explicativ, cum ar fi InputIsNegativeError . Dar această excepție nu este o excepție Python încorporată.
Deci, mai întâi, ne creăm clasa de bază care va deriva din Excepție.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
Apoi creăm clasa noastră de excepție care va moșteni clasa de bază și va gestiona eroarea noastră specifică.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Să testăm acest lucru
try: value = int(input()) if value <0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print('Input value shouldn't be negative')
Cererea de cod de mai sus pentru introducerea utilizatorului și verificați dacă este negativă. Dacă este adevărat, ne ridică excepția personalizată InputIsNegativeError, care este ulterior prinsă în declarația except.
Mai jos este codul complet:
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass if __name__ == '__main__': try: value = int(input('Input a number: ')) if value <0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print('Input value shouldn't be negative')
Dacă valoarea de intrare este un număr negativ ca -1, atunci vom avea rezultatul:
îmbinare interioară îmbinare exterioară unire stângă îmbinare dreaptă
Verificați Python doc pentru mai multe detalii despre excepțiile personalizate Python.
întrebări frecvente
Q # 1) Cum gestionează Python o excepție?
Răspuns: Python gestionează excepțiile folosind declarație try-except . Codul care poate genera o excepție este plasat și executat în încercați să blocați in timp ce cu excepția blocului deține codul care va gestiona excepțiile dacă apare vreunul.
Q # 2) Ce creează o excepție în Python?
Răspuns: Ori de câte ori interpretul Python întâlnește un cod nevalid, acesta ridică o excepție, care este modul propriu al Python de a ne spune că s-a întâmplat ceva neașteptat. La fel de bine putem ridica în mod intenționat excepții folosind declarație de ridicare .
Î # 3) Cum gestionează Python mai multe excepții?
Răspuns: Python gestionează mai multe excepții folosind fie un singur bloc cu excepția blocurilor, fie multiple cu excepția blocurilor.
Pentru un singur bloc, excepțiile sunt transmise ca un tuplu: cu exceptia (Exception1, Exception2, .., ExceptionN) și Python verifică dacă există o potrivire de la dreapta la stânga. În acest caz, se ia aceeași acțiune pentru fiecare excepție.
O altă modalitate de a prinde toate excepțiile este de a lăsa numele excepției după cuvântul cheie exceptat.
except: # handle all exceptions here
A doua modalitate este de a utiliza un bloc cu excepția pentru fiecare excepție:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
În acest fel, puteți efectua acțiuni separate pentru fiecare excepție.
Î # 4) De ce este importantă gestionarea excepțiilor în Python?
Răspuns: Avantajul gestionării excepțiilor în Python este că putem crea aplicații robuste, curate și fără erori. Nu vom dori ca codul nostru de producție să se blocheze din cauza unor erori, așa că gestionăm erorile și menținem aplicația funcțională.
Q # 5) Cum ignorați o excepție în Python?
Răspuns: Pentru a ignora o excepție în Python, utilizați trece cuvânt cheie în blocul cu excepția. Să presupunem că vrem să ignorăm excepția ValueError. Vom face acest lucru:
except ValueError: pass
Dacă nu știi ce faci, este o practică proastă să ignori excepțiile. Cel puțin, informați utilizatorul despre toate erorile potențiale.
Concluzie
În acest tutorial, am tratat: Excepții Python, Traceback; cum să gestionați excepțiile cu Încerca / Cu exceptia / Altfel / In cele din urma blocuri, cum să A ridica Excepții și, în cele din urmă, cum să creăm propriile noastre excepții personalizate.
Mulțumesc pentru lectură!
=> Vizitați aici pentru a afla Python de la zero.
Lectură recomandată
- Tutorial Python pentru începători (Instruire gratuită gratuită Python)
- Instrucțiuni de control Python (Python Continue, Break and Pass)
- Tutorial Python DateTime cu exemple
- Funcții Python String
- Variabile Python
- Tutorial de gestionare a excepțiilor C # cu exemple de cod
- Ghid complet pentru gestionarea excepțiilor PL SQL cu exemple
- Excepții Java și gestionarea excepțiilor cu exemple