python try except python handling exception with examples
Aquest tutorial explica el maneig d'excepcions a Python mitjançant el bloc Prova excepte amb l'ajut d'exemples de programació:
Dos tipus d'errors poden fer que un programa Python s'aturi bruscament, és a dir, Errors de sintaxi , i Excepcions . En aquest tutorial, parlarem del segon tipus d'error (excepcions) en diversos temes importants.
Ens beneficiarem molt de gestionar excepcions a la nostra aplicació, com ara:
- Creació d’una aplicació robusta.
- Creació d’un codi net i sense errors.
=> Visiteu aquí la sèrie exclusiva de tutorials de formació Python
Què aprendreu:
- Prova Python excepte
- Excepcions comunes de Python
- Conclusió
Prova Python excepte
Una bona notícia és que Python té un bon nombre d’excepcions incorporades per detectar errors al nostre codi. A més, ens dóna l'oportunitat de crear excepcions personalitzades quan cap de les excepcions integrades s'adapti a les nostres necessitats.
Què és una excepció
Llavors, què és una excepció a Python? Bé, en termes senzills, sempre que l’intèrpret de Python intenta executar codi no vàlid, genera una excepció i, en els casos en què aquesta excepció no es gestiona, interromp el flux normal de les instruccions del programa i imprimeix un rastreig.
Creem un codi no vàlid i vegem com respondrà l’intèrpret de Python.
Obriu un intèrpret d’ordres de Python i executeu el codi següent.
>>> 50/0
Aquest és un dels errors més freqüents en la programació. El codi anterior intenta dividir el nombre 50 per 0 (zero). L'intèrpret de Python veu això com una operació no vàlida i genera un ZeroDivisionError , interromp el programa i imprimeix un rastreig.
Ho podem veure clar ZeroDivisionError és l'excepció que es va plantejar. De fet, és la manera pròpia de Python de dir-nos que no és genial dividir un nombre per zero. Tot i que en altres idiomes com JavaScript, això no és un error; i python prohibeix estrictament aquesta pràctica.
A més, és important saber que aquest és només un objecte d’excepció i que Python té molts d’aquests objectes incorporats. Mireu aquest oficial de Python documentació per veure totes les excepcions integrades de Python.
Comprendre el Traceback
Abans de començar a tractar excepcions, crec que ajudarà a entendre què passarà exactament si no es gestionen les excepcions i com Python fa tot el possible per informar-nos sobre el nostre error.
Sempre que Python troba un error, genera una excepció. Si no es gestiona aquesta excepció, produeix una informació anomenada Traceback. Llavors, quina informació conté aquest rastreig?
Conté:
- El missatge d'error que ens indica quina excepció s'ha generat i què ha passat abans que s'hagi generat aquesta excepció.
- Els diversos números de línia del codi que han provocat aquest error. Un error pot ser causat per una seqüència de trucades a funcions anomenades a pila de trucades que parlarem més endavant aquí.
Tot i que és una mica confús, prometem que el següent exemple aportarà més llum a la nostra comprensió.
Recordem el traçat que es va imprimir dividint 50 per 0 anterior, podem veure que el traçat conté la informació següent:
- Fitxer '': ens indica que aquest codi s'ha executat des d'una terminal de consola.
- línia 1: ens indica que l'error s'ha produït en aquest número de línia.
- ZeroDivisionError: divisió per zero: Ens indica quina excepció es va plantejar i què la va provocar.
Provem un altre exemple i potser veurem com pila de trucades sembla. Obriu un editor, introduïu el codi següent i deseu-ho com a 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
Obriu un terminal al directori on es troba aquest fitxer i executeu-lo.
què es pot fer amb c ++
python tracebackExp.py
Veureu el següent rastreig:
El traçat anterior pot semblar confús, però en realitat no ho és. Els pitonistes van trobar la millor manera de llegir traceback, que prové de de baix cap amunt . Per tant, fem servir aquesta saviesa per comprendre què pot oferir aquest rastreig.
- A la part inferior, obtenim l’excepció que es va plantejar i per què es va plantejar.
- Avançant, obtenim el nom del fitxer tracebackExp .py on s’ha produït aquest error, el càlcul que ha provocat aquest error compute = numb / div, la funció stack2 i la línia de número d’enllaç 6 on s’ha realitzat aquest càlcul.
- Avançant, veiem que la nostra funció stack2 es va cridar a la funció stack1 de la línia número 3.
- Passant a la part superior, veiem que la funció stack1 es va cridar a la línia número 11.< mòdul > ens diu que és el fitxer que s'està executant.
Excepcions comunes de Python
La biblioteca Python defineix una gran quantitat d'excepcions integrades. Podeu consultar la documentació de Python o trucar al dispositiu integrat local () Funciona de la següent manera:
>>> dir(locals()('__builtins__'))
No intentarem abordar totes aquestes excepcions, però veurem algunes excepcions habituals que probablement trobareu.
# 1) TypeError
Es planteja quan s'aplica una operació o funció a un objecte de tipus inadequat.
Exemple 1
Penseu en el programa següent. Pren un dividend i un divisor i, a continuació, calcula i imprimeix el resultat de dividir el dividend pel divisor.
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()
Demanem a l'usuari el valor del dividend i del divisor, però ens oblidem de convertir el valor de la cadena del divisor en un enter. Per tant, acabem amb el tipus de dividend sencer ( int ) i el tipus de divisor és una cadena ( pàg ). Després obtenim el TypeError ja que l’operador de divisió (/) no opera en cadenes.
Pot interessar-vos saber que, a diferència de Python, Javascript té tipus coerció que bàsicament converteix un dels tipus d’operands en un valor equivalent al tipus de l’altre operand quan els operands són de tipus diferents.
# 2) ValueError
Això es planteja quan una operació o funció rep un argument que té el tipus adequat però un valor inadequat.
Exemple 2
Penseu en el nostre programa a Exemple 1 a sobre.
Si l'usuari introdueix un valor alfanumèric per al dividend com ara '3a', el nostre programa augmentarà l'excepció ValueError. Això es deu, tot i que Python int () El mètode inclou qualsevol número o cadena i retorna un objecte enter; el valor de la cadena no ha de contenir lletres ni cap valor no numèric.
# 3) Error d'atribut
Aquesta excepció es genera quan s’assigna o fa referència a un atribut que no existeix.
Exemple 3
Penseu en el programa següent. Pren un nombre i calcula la seva arrel quadrada amb el fitxer Mòdul matemàtic 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
Quan un usuari introdueix un número, el nostre programa intenta utilitzar una funció del mòdul matemàtic per calcular la seva arrel quadrada, però només aquí hem comès un error. En lloc de sqrt, hem escrit per error sqr que no existeix al mòdul matemàtic.
Per tant, intentàvem fer referència a un atribut sqr que no existeix i va provocar que es generés l'excepció AttributeError. La majoria de nosaltres cometem molt aquest tipus d’errors. Per tant, no esteu sols.
Gestió d'excepcions amb Prova excepte
Com a programador, una cosa en la qual passarem el nostre temps és escriure un codi robust que sigui resistent. Codi que no es trenca a causa d'alguns errors. A Python, podem aconseguir-ho adjuntant les nostres declaracions a provar - excepte declaració.
Instrucció Python Try-Except
La sentència try-except té la següent estructura:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Incloem el codi a tracebackExp .py dins d’una sentència 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
L'execució d'aquest codi produirà la sortida
Així funciona la sentència try-except. Python executa el codi al bloc try línia 7-8 . Si no es troba cap codi no vàlid, el codi del bloc excepte línia 10 s'omet i l'execució continua.
Però, si es troba un codi no vàlid, l'execució s'atura immediatament al bloc try i comprova si l'excepció plantejada coincideix amb la que hem proporcionat a la sentència except línia 9 . Si coincideix, s'executa el bloc excepte i continua. Si no ho fa, el programa s’interromprà.
El bloc de prova normalment conté el codi que pot generar una excepció mentre que el bloc d’excepció captura i gestiona l’excepció.
Gestió de diverses excepcions amb excepte
Podem gestionar diverses excepcions amb un únic 'excepte' o amb diverses 'excepcions'. Tot depèn de com vulgueu gestionar cada excepció.
# 1) Gestió de diverses excepcions amb un únic excepte
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Aquest mètode s’utilitza quan sospitem que el nostre codi pot generar excepcions diferents i volem fer la mateixa acció en cada cas. Per tant, si l’intèrpret de Python troba una coincidència, s’executarà el codi escrit al bloc excepte.
Vegem l'exemple de codi Python següent
proves funcionals vs proves no funcionals
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)
Tenim dues possibles excepcions que es poden plantejar aquí, ZeroDivisionError i IndexError . Si es planteja alguna d’aquestes excepcions, s’executarà el bloc except.
Al codi anterior, idx = 3, de manera que idx_ valor passa a ser 0 i valor / idx_ valor generarà ZeroDivisionError
# 2) Gestió de diverses excepcions amb diverses excepcions
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Si preferim gestionar cada excepció per separat, així és com podeu fer-ho.
Considereu l'exemple del codi Python següent
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
Aquí observem que Exception es va utilitzar a la darrera sentència except. Això es deu al fet que l'objecte Exception Exception coincideix amb qualsevol excepció. Per aquest motiu, sempre hauria de ser l’últim, ja que Python deixarà de comprovar altres controladors d’excepcions un cop coincideixi.
Al codi anterior, idx = 5 , per tant arr (idx) pujarà IndexError perquè idx és superior a la longitud de la llista arr
A més, no estic segur de quina excepció es va plantejar amb la vostra aplicació. Per això, tenim el tipus Excepció per detectar qualsevol excepció no prevista. A continuació, informem l’usuari i interrompem l’aplicació elevant la mateixa excepció.
Proveu la declaració Else
Això és un característica opcional de maneig d’excepcions i us permet afegir codi que vulgueu executar quan no es produeixi cap error. Si es produeix un error, aquest bloc d’altres no s’executarà.
Penseu en l'exemple següent del codi Python, obriu l'editor i deseu el codi com 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
Rebem l'entrada de l'usuari i la fem servir per dividir 1. Tenim dues possibles excepcions aquí, una entrada d'usuari no vàlida que provocarà ValueError i a zero (0) que provocarà ZeroDivisionError . La nostra declaració excepte gestiona aquests errors.
Ara volem imprimir el valor de valor . El nostre bloc else assegura que s’imprimeix només si el bloc try s’executa sense cap error. Això és important perquè si es produeix un error al nostre bloc de proves, el fitxer valor quedarà indefinit. Per tant, accedir-hi generarà un altre error.
Executeu el codi anterior amb Python elseTry.py
La sortida anterior mostra que, per a la primera entrada, hem escrit 0 i premeu ENTER. Com que el nostre divisor ha rebut 0, 1 / divisor augmentat zeroDivisionError . La nostra segona entrada va ser k, que no és vàlida int (), d’aquí l’excepció ValueError es planteja.
Però la nostra darrera entrada va ser 9, que és vàlida i, com a resultat, vam obtenir el valor de ' valor ”Imprès com a 0.1111111111111111
Proveu finalment la declaració
Això també és un característica opcional de manipulació d’excepcions i s’executarà sempre passi el que passi als controladors d’excepcions.
Això és:
- Si es produeix o no una excepció
- Fins i tot si es fa una 'devolució' als altres blocs.
- Fins i tot si l'script es deixa als altres blocs
Per tant, si tenim un codi que volem executar en totes les situacions, finalment el bloc és el nostre tipus. Aquest bloc s'utilitza principalment per a netejes com ara tancar fitxers.
Considereu l'exemple del codi Python següent
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)
Aquest codi intenta obrir i llegir el fitxer text.txt al directori actual. Si el fitxer existeix, el nostre programa imprimirà la primera línia del fitxer, llavors el bloc final s'executarà i el tancarà.
Suposem que tenim un fitxer anomenat text.txt al directori on es troba aquest fitxer de programa i que conté Hello. Si executem el programa, tindrem la sortida
Aquest exemple s'ha escollit intencionadament perquè volia que solucionéssim un petit problema que es podria produir en tancar fitxers al bloc final.
Si el fitxer no existeix, l’excepció FileNotFoundError s'aixecarà i la variable Arxiu obert no es definirà ni serà un objecte de fitxer. Per tant, intentar tancar-lo al bloc final plantejarà una excepció UnboundLocalError que és una subclasse de NameError .
Això bàsicament diu que estem intentant fer referència a la variable Arxiu obert abans que s’hagi assignat.
Un petit truc aquí és utilitzar controladors d’excepcions dins del bloc 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)
Si el nostre bloc de prova provoca FileNotFoundError, tindrem la següent sortida
Augmentar l'excepció
Una bona notícia sobre les excepcions de Python és que les podem plantejar intencionadament. Les excepcions es plantegen amb el declaració augmentar .
La sentència raise té la sintaxi següent:
raise (ExceptionName((*args: Object)))
Obriu un terminal i aixequeu qualsevol objecte d'excepció del fitxer Excepcions integrades a Python. Per exemple, si plantegem ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Obtindrem el rastreig:
Per tant, per què és important plantejar excepcions?
- Quan es treballa amb excepcions personalitzades.
- Durant les comprovacions del seny.
Classes d’excepcions personalitzades
Una excepció personalitzada és la que creeu per gestionar els errors específics de la vostra necessitat. El truc és que definim una classe que deriva de l’objecte Excepció , a continuació, fem servir la sentència raise per augmentar la nostra classe d'excepció.
Suposem que volem comprovar l’entrada de l’usuari i assegurar-nos que el valor d’entrada no és negatiu (comprovació del seny). Per descomptat, podríem generar l’excepció de Python ValueError, però ens agradarà personalitzar l’error donant-li un nom específic i que s’explica per si mateix, com InputIsNegativeError . Però aquesta excepció no és una excepció integrada a Python.
Per tant, primer, creem la nostra classe base que derivarà de l’excepció.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
A continuació, creem la nostra classe d'excepció que heretarà la classe base i gestionarà el nostre error específic.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Anem a provar-ho
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')
La sol·licitud de codi anterior per introduir l’usuari i comprovar si és negativa. Si és cert, augmenta la nostra excepció personalitzada InputIsNegativeError, que posteriorment es captura a la sentència except.
A continuació es mostra el codi complet:
aplicacions de Java al món real
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')
Si el valor d'entrada és un nombre negatiu com -1, tindrem la sortida:
Consulteu el Python doc per obtenir més informació sobre les excepcions personalitzades de Python.
Preguntes freqüents
P # 1) Com gestiona Python una excepció?
Resposta: Python gestiona les excepcions mitjançant el fitxer declaració try-except . El codi que pot generar una excepció es col·loca i s'executa al fitxer prova de bloquejar mentre que excepte bloc conté el codi que gestionarà les excepcions si sorgeix alguna.
Q # 2) Què planteja una excepció a Python?
Resposta: Sempre que l’intèrpret de Python troba un codi no vàlid, genera una excepció, que és la manera pròpia de Python de dir-nos que ha passat alguna cosa inesperada. També podem plantejar excepcions intencionadament mitjançant el fitxer declaració augmentar .
P # 3) Com gestiona Python diverses excepcions?
Resposta: Python gestiona diverses excepcions mitjançant un bloc excepte o múltiples excepte blocs.
Per a un bloc únic, les excepcions es passen com a tupla: excepte (Exception1, Exception2, .., ExceptionN) i Python comprova si hi ha coincidències de dreta a esquerra. En aquest cas, es fa la mateixa acció per a cada excepció.
Una altra manera d’atrapar totes les excepcions és deixar de banda el nom de l’excepció després de la paraula clau except.
except: # handle all exceptions here
La segona forma és utilitzar un bloc excepte per a cada excepció:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
D'aquesta manera, podeu fer accions separades per a cada excepció.
Q # 4) Per què és important el tractament d'excepcions a Python?
Resposta: L’avantatge de gestionar excepcions a Python és que podem crear aplicacions robustes, netes i sense errors. No voldrem que el nostre codi de producció es bloquegi a causa d’alguns errors, de manera que gestionem els errors i mantenim la nostra aplicació en funcionament.
Q # 5) Com s'ignora una excepció a Python?
Resposta: Per ignorar una excepció a Python, utilitzeu el fitxer passar paraula clau del bloc excepte. Suposem que volem ignorar l'excepció ValueError. Ho farem així:
except ValueError: pass
Llevat que sàpiga què feu, és una mala pràctica ignorar les excepcions. Com a mínim, informeu l’usuari de tots els possibles errors.
Conclusió
En aquest tutorial, hem tractat: Python Exceptions, Traceback; com gestionar les excepcions amb Proveu-ho / Excepte / Altrament / Finalment blocs, com Aixeca Excepcions i, finalment, com crear les nostres pròpies excepcions personalitzades.
Gràcies per llegir!
=> Visiteu aquí per aprendre Python des de zero.
Lectura recomanada
- Tutorial Python per a principiants (entrenament pràctic GRATU PyT en Python)
- Instruccions de control de Python (Python Continue, Break and Pass)
- Tutorial de Python DateTime amb exemples
- Funcions de cadena de Python
- Variables de Python
- Tutorial de maneig d'excepcions C # amb exemples de codi
- Guia completa del maneig d'excepcions PL SQL amb exemples
- Excepcions de Java i tractament d’excepcions amb exemples