python try except python handling exception with examples
Denna handledning förklarar Exception Handling i Python med hjälp av Try Except-blocket med hjälp av programmeringsexempel:
Två feltyper kan orsaka att ett Python-program slutar plötsligt, dvs. Syntaxfel och Undantag . I den här handledningen kommer vi att diskutera den andra feletypen (Undantag) under flera viktiga ämnen.
Vi kommer att ha mycket nytta av att hantera undantag i vår applikation som:
- Skapa en robust applikation.
- Skapa en ren och felfri kod.
=> Besök här för den exklusiva Python Training Tutorial Series
Vad du kommer att lära dig:
- Python Prova utom
- Vanliga Python-undantag
- Slutsats
Python Prova utom
En god nyhet är att Python har ett stort antal inbyggda undantag för att fånga fel i vår kod. Det ger oss också möjlighet att skapa anpassade undantag när inget av de inbyggda undantagen passar våra behov.
Vad är ett undantag
Så vad är ett undantag i Python? Enkelt uttryckt, när Python-tolk försöker köra ogiltig kod, ger det ett undantag, och i de fall där ett sådant undantag inte hanteras stör det det normala flödet av programmets instruktioner och skriver ut en spårning.
Låt oss skapa en ogiltig kod och se hur Python-tolk kommer att svara.
Öppna ett Python-skal och kör följande kod.
>>> 50/0
Detta är ett av de vanligaste felen i programmeringen. Ovanstående kod försöker dela upp numret femtio förbi 0 (noll). Python-tolken ser detta som en ogiltig åtgärd och höjer en ZeroDivisionError , stör programmet och skriver ut en spårning.
Det kan vi tydligt se ZeroDivisionError är undantaget som togs upp. Det är verkligen Pythons eget sätt att berätta att det inte är coolt att dela ett tal med noll. Men på andra språk som JavaScript är detta inte ett fel. och python strängt förbjuder denna praxis.
Det är också viktigt att veta att detta bara är ett undantagsobjekt och Python har många sådana objekt inbyggda. Kolla in den här Python-tjänstemannen dokumentation för att se alla Pythons inbyggda undantag.
Förstå spårning
Innan vi börjar hantera undantag tror jag att det kommer att hjälpa oss att förstå vad som exakt kommer att hända om undantag inte hanteras och hur Python gör sitt bästa för att informera oss om vårt fel.
Närhelst Python stöter på ett fel ger det ett undantag. Om detta undantag inte hanteras producerar det viss information som heter Traceback. Så vilken information innehåller denna spårning?
Det innehåller:
- Felmeddelandet som berättar vilket undantag som togs upp och vad som hände innan detta undantag togs upp.
- De olika radnumren på koden som orsakade detta fel. Ett fel kan orsakas av en sekvens av funktionssamtal som kallas a samtalsstack som vi kommer att diskutera senare här.
Även om det är lite förvirrande, lovar vi att nästa exempel kommer att ge mer ljus till vår förståelse.
Kom ihåg traceback som trycktes från att dela 50 med 0 ovan, vi kan se att traceback innehåller följande information:
- File “”: Detta säger att den här koden kördes från en konsolterminal.
- rad 1: Detta talar om för oss att felet inträffade i detta radnummer.
- ZeroDivisionError: uppdelning efter noll: Det berättar vilket undantag som togs upp och vad som orsakade det.
Låt oss prova ett annat exempel och kanske se hur en samtalsstack ser ut som. Öppna en redigerare, ange koden nedan och spara som 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
Öppna en terminal i katalogen där filen hittas och körs.
python tracebackExp.py
Du kommer att se följande spårning:
Ovanstående spårning kan verka förvirrande men egentligen är det inte. Pythonistas kom med det bästa sättet att läsa spårning, som är från botten upp . Så, låt oss använda denna visdom för att försöka förstå vad denna spårning har att erbjuda.
- Längst ner får vi undantaget som höjdes och varför det höjdes.
- När vi flyttar upp får vi filnamnet tracebackExp .py där detta fel inträffade, beräkningen som orsakade detta fel beräkning = numb / div, funktionen stack2 och länknummerrad 6 där denna beräkning utfördes.
- När vi flyttar upp ser vi att vår stack2-funktion anropades i funktion stack1 i rad nummer 3.
- När vi går till det översta ser vi att funktionen stack1 anropades i rad nummer 11.< modul > berättar att det är filen som körs.
Vanliga Python-undantag
Python-biblioteket definierar väldigt många inbyggda undantag. Du kan kontrollera Python-dokumentationen eller ringa den inbyggda lokal () fungerar som nedan:
>>> dir(locals()('__builtins__'))
Vi kommer inte att försöka ta itu med alla dessa undantag, men vi kommer att se några vanliga undantag som du troligen kommer att stöta på.
# 1) TypeError
Den höjs när en operation eller funktion tillämpas på ett objekt av olämplig typ.
Exempel 1
Tänk på programmet nedan. Det tar in en utdelning och delare, sedan beräknar och skriver ut resultatet av att dela utdelningen med delaren.
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()
Vi begär värdet på utdelningen och delaren från användaren, men vi glömmer att kasta delarens strängvärde i ett heltal. Så slutar vi med att utdelningstypen är heltal ( int ) och delarens typ är sträng ( sid ). Vi får sedan Skrivfel eftersom avdelningsoperatören (/) inte arbetar på strängar.
Det kan intressera dig att veta att Javascript till skillnad från Python har typtvingning som i grunden omvandlar en av operandens typer till ett motsvarande värde av den andra operandens typ när operanderna är av olika typ.
# 2) ValueError
Detta tas upp när en operation eller funktion får ett argument som har rätt typ men ett olämpligt värde.
Exempel 2
Tänk på vårt program i Exempel 1 ovan.
Om användaren matar in ett alfanumeriskt värde för utdelningen som ”3a”, kommer vårt program att höja ValueError-undantaget. Detta beror på, även om Python int () metoden tar in valfritt tal eller sträng och returnerar ett heltalobjekt, strängvärdet bör inte innehålla bokstäver eller något icke-numeriskt värde.
# 3) AttributeError
Detta undantag tas upp när du tilldelar eller refererar till ett attribut som inte finns.
Exempel 3
Tänk på programmet nedan. Den tar in ett tal och beräknar kvadratroten med hjälp av Python-matematikmodul
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
När en användare anger ett nummer försöker vårt program använda en funktion från matematikmodulen för att beräkna dess kvadratrot men just här gjorde vi ett fel. I stället för sqrt skrev vi felaktigt sqr som inte finns i matematikmodulen.
Så vi försökte referera till ett attribut sqr som inte finns och ledde till att undantaget AttributeError höjdes. De flesta av oss gör denna typ av misstag mycket. Så du är inte ensam.
Hantera undantag med försök utom
Som programmerare är en sak som de flesta av oss kommer att spendera vår tid på att skriva en robust kod som är motståndskraftig. Kod som inte går sönder på grund av vissa fel. I Python kan vi uppnå detta genom att bifoga våra uttalanden i en Prova - bortsett från påstående.
Python Try-Except-uttalande
Try-except-uttalandet har följande struktur:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Låt oss bifoga koden i tracebackExp .py inuti ett försök utom uttalande.
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
Att köra den här koden kommer att producera utdata
Så här fungerar försöks utom-uttalandet. Python kör koden i försöksblocket rad 7-8 . Om ingen ogiltig kod hittas, kommer koden i undantagsblocket rad 10 hoppas över och körningen fortsätter.
Men om en ogiltig kod hittas, stannar körningen omedelbart i försöksblocket och kontrollerar om det upptagna undantaget matchar det som vi angav i undantagssatsen rad 9 . Om det matchar körs undantagsblocket och fortsätter. Om den inte gör det, avbryts programmet.
Try-blocket innehåller vanligtvis koden som kan höja ett undantag medan exception-blocket fångar och hanterar undantaget.
Hantering av flera undantag utom
Vi kan hantera flera undantag med antingen ett enda 'utom' eller flera 'undantag'. Allt beror på hur du vill hantera varje undantag.
# 1) Hantering av flera undantag med ett enda undantag
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Denna metod används när vi misstänker att vår kod kan ge olika undantag och vi vill vidta samma åtgärder i varje fall. Så om Python-tolken hittar en matchning kommer koden skriven i undantagsblocket att köras.
Låt oss överväga exemplet Python-kod nedan
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)
Vi har två möjliga undantag som kan tas upp här, ZeroDivisionError och Indexfel . Om något av dessa undantag tas upp kommer undantagsblocket att köras.
I koden ovan, idx = 3, så idx_ värde blir 0 och värde / idx_ värde kommer att höja ZeroDivisionError
# 2) Hantering av flera undantag med flera undantag
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Om vi hellre vill hantera varje undantag separat, så kan du göra det.
Tänk på exemplet Python-kod nedan
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
Vi märker här att Undantag användes i det sista utom uttalandet. Detta beror på att undantagsobjektet Undantag matchar alla undantag. Av den anledningen bör det alltid vara sist eftersom Python slutar kontrollera andra undantagshanterare när en matchar.
I koden ovan, idx = 5 , därmed arr (idx) kommer att höja Indexfel eftersom idx är större än listans längd arr
Inte säker på vilket undantag som togs upp av din ansökan är aldrig säkert att fortsätta körningen. Det är därför vi har typen Undantag för att fånga alla oförutsedda undantag. Sedan informerar vi användaren och avbryter applikationen genom att göra samma undantag.
Prova Else Statement
Detta är en valfri funktion av undantagshantering och låter dig lägga till kod som du vill köra när inga fel inträffade. Om ett fel inträffar körs detta annat block inte.
Tänk på exemplet Python-kod nedan, öppna din redigerare och spara koden som 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
Vi får input från användaren och använder den för att dela 1. Vi har två möjliga undantag här, en ogiltig användarinmatning som kommer att orsaka ValueError och a noll (0) som kommer att orsaka ZeroDivisionError . Vårt utom uttalande hanterar dessa fel.
Nu vill vi skriva ut värdet på värde . Vårt annat block ser till att det bara skrivs ut om vårt försöksblock körs utan ett fel. Detta är viktigt eftersom om ett fel uppstår i vårt försöksblock, värde kommer att vara odefinierad. Så att få tillgång till det kommer att leda till ett annat fel.
Kör koden ovan med Python elseTry.py
Utgången ovan visar att för den första inmatningen skrev vi 0 och tryckte på ENTER. Eftersom vår divisor fick 0, höjdes 1 / divisor zeroDivisionError . Vår andra ingång var k vilket är ogiltigt för int (), därav undantaget ValueError höjs.
Men vår senaste inmatning var 9 vilket är giltigt och som ett resultat fick vi värdet av “ värde ”Tryckt som 0.1111111111111111
Försök slutligen uttalande
Detta är också en valfri funktion undantagshantering och kommer alltid att fungera oavsett vad som händer i undantagshanterarna.
Det är:
- Huruvida ett undantag inträffar eller inte
- Även om en ”retur” kallas i de andra blocken.
- Även om manuset avslutas i andra block
Så om vi har en kod som vi vill köra i alla situationer, är block-äntligen vår kille. Detta block används oftast för saneringar som att stänga filer.
Tänk på exemplet Python-kod nedan
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)
Den här koden försöker öppna och läsa filen text.txt i sin nuvarande katalog. Om filen existerar kommer vårt program att skriva ut den första raden i filen så kör vårt slutliga block och stänger filen.
Anta att vi har en fil som heter text.txt i katalogen där den här programfilen finns och innehåller Hej. Om vi kör programmet får vi utdata
Detta exempel valdes avsiktligt eftersom jag ville att vi skulle ta itu med ett litet problem som kan uppstå när filer stängs i slutblocket.
Om filen inte finns, undantaget FileNotFoundError kommer att höjas och variabeln öppna fil kommer inte att definieras och kommer inte att vara ett filobjekt. Att försöka stänga det i slutblocket kommer därför att leda till ett undantag Obundet Lokalfel som är en underklass av NameError .
Detta säger i princip att vi försöker referera till variabeln öppna fil innan den har tilldelats.
Ett litet knep här är att använda undantagshanterare i slutblocket.
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)
Om vårt försök blockerar FileNotFoundError, kommer vi att ha följande utdata
Höj undantaget
En god nyhet om Python-undantag är att vi medvetet kan höja dem. Undantag tas upp med höja uttalande .
Upphöjningsuttalandet har följande syntax:
raise (ExceptionName((*args: Object)))
Öppna en terminal och lyft alla undantagsobjekt från Inbyggda Python-undantag. Till exempel, om vi höjer ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Vi får spårningen:
Så varför är det viktigt att ta upp undantag?
- När du arbetar med anpassade undantag.
- Under sanity-kontroller.
Anpassade undantagskurser
Ett anpassat undantag är ett som du skapar för att hantera fel som är specifika för ditt behov. Tricket är att vi definierar en klass som härrör från objektet Undantag , sedan använder vi höjningsuttalandet för att höja vår undantagsklass.
Antag att vi vill kontrollera användarinmatningen och se till att ingångsvärdet inte är negativt (sanity check). Naturligtvis kan vi höja Python-undantaget ValueError men vi vill anpassa felet genom att ge det ett specifikt och självförklarande namn som InputIsNegativeError . Men detta undantag är inte ett inbyggt Python-undantag.
Så först skapar vi vår basklass som kommer från Undantag.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
Sedan skapar vi vår undantagsklass som kommer att ärva basklassen och hanterar vårt specifika fel.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Låt oss testa detta
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')
Ovanstående kodbegäran för användarinmatning och kontrollera om den är negativ. Om det är sant höjer det vårt anpassade undantag InputIsNegativeError som senare fångas i undantagsuttalandet.
Nedan är den fullständiga koden:
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')
Om ingångsvärdet är ett negativt tal som -1 kommer vi att ha utdata:
hur testar du webbtjänster
Kolla in Python doc för mer information om anpassade Python-undantag.
Vanliga frågor
F # 1) Hur hanterar Python ett undantag?
Svar: Python hanterar undantag med hjälp av försök utom uttalande . Koden som kan ge ett undantag placeras och körs i försök blockera medan utom block innehar koden som hanterar undantagen om någon uppstår.
F # 2) Vad ger ett undantag i Python?
Svar: Närhelst Python-tolk stöter på en ogiltig kod, ger det ett undantag, vilket är Pythons eget sätt att berätta för oss att något oväntat hände. Vi kan också avsiktligt höja undantag med hjälp av höja uttalande .
F # 3) Hur hanterar Python flera undantag?
Svar: Python hanterar flera undantag med antingen ett enda förutom block eller flera utom block.
För ett enda block skickas undantagen som en tuple: bortsett från (Exception1, Exception2, .., ExceptionN) och Python söker efter en matchning från höger till vänster. I det här fallet vidtas samma åtgärder för varje undantag.
Ett annat sätt att fånga alla undantag är att utesluta namnet på undantaget efter det undantagna nyckelordet.
except: # handle all exceptions here
Det andra sättet är att använda ett undantagsblock för varje undantag:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
På så sätt kan du vidta separata åtgärder för varje undantag.
F # 4) Varför är undantagshantering viktigt i Python?
Svar: Fördelen med att hantera undantag i Python är att vi kan skapa robusta, rena och felfria applikationer. Vi vill inte att vår produktionskod ska krascha på grund av vissa fel, så vi hanterar felen och håller vår applikation igång.
F # 5) Hur ignorerar du ett undantag i Python?
Svar: För att ignorera ett undantag i Python, använd passera nyckelord i undantagsblocket. Låt oss säga att vi vill ignorera ValueError-undantaget. Vi kommer att göra det så här:
except ValueError: pass
Om du inte vet vad du gör är det dåligt att ignorera undantag. Informera åtminstone användaren om alla potentiella fel.
Slutsats
I denna handledning behandlade vi: Python Exception, Traceback; hur man hanterar undantag med Prova / Bortsett från / Annan / Till sist block, hur man Höja Undantag och slutligen hur man skapar våra egna anpassade undantag.
Tack för att du läser!
=> Besök här för att lära dig Python From Scratch.
Rekommenderad läsning
- Python-handledning för nybörjare (praktisk Python-träning)
- Python Control Statements (Python Fortsätt, Break och Pass)
- Python DateTime-handledning med exempel
- Python-strängfunktioner
- Python-variabler
- C # Handledning för undantagshantering med kodexempel
- Komplett guide till PL SQL-undantagshantering med exempel
- Java-undantag och undantagshantering med exempel