python try except python handling exception with examples
Denne tutorial forklarer undtagelseshåndtering i Python ved hjælp af Try Except-blokken ved hjælp af programmeringseksempler:
To fejltyper kan få et Python-program til at stoppe brat, dvs. Syntaksfejl og Undtagelser . I denne vejledning diskuterer vi den anden fejltype (undtagelser) under flere vigtige emner.
Vi vil have meget ud af at håndtere undtagelser i vores ansøgning som:
- Oprettelse af en robust applikation.
- Oprettelse af en ren og fejlfri kode.
=> Besøg her for den eksklusive Python Training Tutorial-serie
Hvad du vil lære:
- Python Prøv undtagen
- Almindelige Python-undtagelser
- Konklusion
Python Prøv undtagen
En god nyhed er, at Python har et stort antal indbyggede undtagelser for at fange fejl i vores kode. Det giver os også mulighed for at oprette brugerdefinerede undtagelser, når ingen af de indbyggede undtagelser passer til vores behov.
Hvad er en undtagelse
Så hvad er en undtagelse i Python? Når det er simpelt sagt, når Python-tolken forsøger at udføre ugyldig kode, rejser den en undtagelse, og i de tilfælde hvor en sådan undtagelse ikke håndteres, forstyrrer den den normale strøm af programmets instruktioner og udskriver et spor.
Lad os oprette en ugyldig kode og se, hvordan Python-tolken vil reagere.
Åbn en Python-skal, og kør følgende kode.
>>> 50/0
Dette er en af de mest almindelige fejl i programmeringen. Ovenstående kode forsøger at opdele nummeret halvtreds ved 0 (nul). Python-tolken ser dette som en ugyldig handling og rejser en ZeroDivisionError , forstyrrer programmet og udskriver et spor.
Det kan vi tydeligt se ZeroDivisionError er den undtagelse, der blev rejst. Det er faktisk Pythons egen måde at fortælle os, at det ikke er sejt at dele et tal med nul. Selvom det på andre sprog som JavaScript ikke er en fejl; og python forbyder strengt denne praksis.
Det er også vigtigt at vide, at dette kun er et undtagelsesobjekt, og Python har mange sådanne objekter indbygget. Tjek denne Python-embedsmand dokumentation for at se alle de indbyggede Python-undtagelser.
Forståelse af sporingen
Før vi går ind i håndtering af undtagelser, tror jeg, det vil hjælpe med at forstå, hvad der præcist vil ske, hvis undtagelser ikke håndteres, og hvordan Python gør sit bedste for at informere os om vores fejl.
Hver gang Python støder på en fejl, rejser det en undtagelse. Hvis denne undtagelse ikke håndteres, producerer den nogle oplysninger kaldet Traceback. Så hvilke oplysninger indeholder denne traceback?
Det indeholder:
- Fejlmeddelelsen, der fortæller os, hvilken undtagelse der blev rejst, og hvad der skete, før denne undtagelse blev rejst.
- De forskellige linjenumre på koden, der forårsagede denne fejl. En fejl kan være forårsaget af en række funktionsopkald kaldet a opkaldstak som vi vil diskutere senere her.
Selvom det er lidt forvirrende, lover vi, at det næste eksempel vil bringe mere lys til vores forståelse.
Husk det traceback, der blev udskrevet fra at dividere 50 med 0 ovenfor, vi kan se, at tracebacket indeholder følgende oplysninger:
- Fil “”: Dette fortæller os, at denne kode blev kørt fra en konsolterminal.
- linje 1: Dette fortæller os, at fejlen opstod i dette linjenummer.
- ZeroDivisionError: opdele efter nul: Den fortæller os, hvilken undtagelse der blev rejst, og hvad der forårsagede den.
Lad os prøve et andet eksempel og måske se, hvordan en opkaldstak ligner. Åbn en editor, indtast koden nedenfor, og gem 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
Åbn en terminal i biblioteket, hvor denne fil findes og køres.
python tracebackExp.py
Du får vist følgende traceback:
Ovenstående traceback kan virke forvirrende, men virkelig er det ikke. Pythonistas kom op med den bedste måde at læse traceback på, som er fra bunden i vejret . Så lad os bruge denne visdom til at prøve og forstå, hvad denne traceback har at tilbyde.
- Nederst får vi undtagelsen, der blev rejst, og hvorfor den blev rejst.
- Når vi bevæger os op, får vi filnavnet tracebackExp .py hvor denne fejl opstod, beregningen, der forårsagede denne fejl, beregne = numb / div, funktionen stack2 og linknummerlinjen 6, hvor denne beregning blev udført.
- Når vi bevæger os op, ser vi, at vores stack2-funktion blev kaldt i funktionen stack1 i linje nummer 3.
- Når vi går til det øverste, ser vi, at funktionsstakken 1 blev kaldt i linje nummer 11.< modul > fortæller os, at det er filen, der udføres.
Almindelige Python-undtagelser
Python-biblioteket definerer utrolig mange indbyggede undtagelser. Du kan kontrollere Python-dokumentationen eller ringe til den indbyggede lokal () fungerer som nedenfor:
>>> dir(locals()('__builtins__'))
Vi vil ikke forsøge at adressere alle disse undtagelser, men vi vil se et par almindelige undtagelser, som du sandsynligvis vil støde på.
# 1) TypeFejl
Det hæves, når en operation eller funktion anvendes på et objekt af en upassende type.
Eksempel 1
Overvej nedenstående program. Det tager et udbytte og en divisor, beregner og udskriver derefter resultatet af at dividere udbyttet med divisoren.
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 anmoder om værdien af udbyttet og divisoren fra brugeren, men vi glemmer at kaste divisorens strengværdi i et heltal. Så vi ender med at udbyttetypen er heltal ( int ) og divisorens type er streng ( s ). Vi får derefter TypeFejl da divisionsoperatøren (/) ikke opererer på strenge.
Det kan interessere dig at vide, at i modsætning til Python har Javascript Type-tvang, der grundlæggende konverterer en af operandens typer til en ækvivalent værdi af den anden operands type, når operanderne er af forskellige typer.
# 2) ValueError
Dette hæves, når en operation eller funktion modtager et argument, der har den rigtige type, men en upassende værdi.
Eksempel 2
Overvej vores program i Eksempel 1 over.
Hvis brugeren indtaster en alfanumerisk værdi for udbyttet som '3a', så hæver vores program undtagelsen ValueError. Dette skyldes, selvom Python int () Metoden optager et hvilket som helst tal eller en streng og returnerer et heltalobjekt, strengværdien bør ikke indeholde bogstaver eller nogen ikke-numerisk værdi.
# 3) AttributError
Denne undtagelse hæves under tildeling eller henvisning til en attribut, der ikke findes.
Eksempel 3
Overvej programmet nedenfor. Det tager et tal ind og beregner dets kvadratrode ved hjælp af 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 bruger indtaster et nummer, forsøger vores program at bruge en funktion fra matematikmodulet til at beregne dens kvadratrode, men netop her lavede vi en fejl. I stedet for sqrt skrev vi fejlagtigt sqr, der ikke findes i matematikmodulet.
Så vi forsøgte at henvise til en attribut-sqr, der ikke findes, og førte til undtagelsen AttributeError blev rejst. De fleste af os begår denne slags fejl meget. Så du er ikke alene.
Håndtering af undtagelser med Prøv undtagen
Som programmør er en ting, som de fleste af os bruger vores tid på, at skrive en robust kode, der er modstandsdygtig. Kode, der ikke går i stykker på grund af nogle fejl. I Python kan vi opnå dette ved at vedlægge vores udsagn i en prøve - undtagen udmelding.
Python Try-Undtagen udsagn
Try-undtagen udsagnet har følgende struktur:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Lad os vedlægge koden i tracebackExp .py inde i et forsøg undtagen udsagn.
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
At køre denne kode vil producere output
Sådan fungerer udsagnet undtagen. Python udfører koden i prøveblokken linje 7-8 . Hvis der ikke findes nogen ugyldig kode, så koden i undtagelsesblokken linje 10 springes over og udførelsen fortsætter.
Men hvis der findes en ugyldig kode, stopper udførelsen straks i prøveblokken og kontrollerer, om den hævede undtagelse stemmer overens med den, vi har angivet i undtagelseserklæringen linje 9 . Hvis den stemmer overens, udføres undtagelsesblokken og fortsætter. Hvis det ikke gør det, afbrydes programmet.
Try-blokken indeholder normalt den kode, der muligvis hæver en undtagelse, mens den undtagelses-blok fanger og håndterer undtagelsen.
Håndtering af flere undtagelser undtagen
Vi kan håndtere flere undtagelser med enten et enkelt 'undtagen' eller flere 'undtagelser'. Det hele afhænger af, hvordan du vil håndtere hver undtagelse.
# 1) Håndtering af flere undtagelser med et enkelt undtagelse
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Denne metode bruges, når vi har mistanke om, at vores kode kan give forskellige undtagelser, og vi ønsker at tage den samme handling i hvert tilfælde. Så hvis Python-tolken finder et match, udføres koden skrevet i undtagelsesblokken.
Lad os overveje eksemplet nedenfor med Python-kode
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 to mulige undtagelser, der kunne hæves her, ZeroDivisionError og IndexError . Hvis nogen af disse undtagelser hæves, udføres undtagelsesblokken.
I koden ovenfor er idx = 3, så idx_ værdi bliver 0 og værdi / idx_ værdi vil hæve ZeroDivisionError
# 2) Håndtering af flere undtagelser med flere undtagelser
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Hvis vi hellere vil håndtere hver undtagelse separat, så kan du gøre det.
Overvej eksemplet på Python-koden nedenfor
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 bemærker her, at undtagelse blev brugt i den sidste undtagelse. Dette skyldes, at undtagelsesobjektet Undtagelse matcher enhver undtagelse. Af denne grund skal det altid være sidste, da Python holder op med at kontrollere andre undtagelsesbehandlere, når en matcher.
I koden ovenfor, idx = 5 derfor arr (idx) vil hæve IndexError fordi idx er større end længden på listen arr
Også usikker på, hvilken undtagelse der blev rejst af din ansøgning, er aldrig sikkert at fortsætte udførelsen. Derfor har vi typen Undtagelse til at fange eventuelle uforudsete undtagelser. Derefter informerer vi brugeren og afbryder applikationen ved at hæve den samme undtagelse.
Prøv Else Statement
Dette er en valgfri funktion undtagelseshåndtering og giver dig mulighed for at tilføje kode, som du vil køre, når der ikke opstod fejl. Hvis der opstår en fejl, kører denne ellers-blok ikke.
Overvej eksemplet med Python-kode nedenfor, åbn din editor og gem 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 fra brugeren og bruger det til at opdele 1. Vi har to mulige undtagelser her, et ugyldigt brugerinput, som vil medføre ValueError og en nul (0) hvilket vil forårsage ZeroDivisionError . Vores undtagen erklæring håndterer disse fejl.
Nu vil vi udskrive værdien af værdi . Vores ellers-blok sørger for, at den kun udskrives, hvis vores prøve-blok udføres uden en fejl. Dette er vigtigt, for hvis der opstår en fejl i vores prøveblok, er værdi vil være udefineret. Så ved at få adgang til det vil der opstå en anden fejl.
Kør koden ovenfor med Python elseTry.py
Outputtet ovenfor viser, at vi ved det første input skrev 0 og tryk på ENTER. Da vores skillevæg modtog 0, hæves 1 / skillevæg zeroDivisionError . Vores andet input var k, hvilket er ugyldigt for int (), derfor undtagelsen ValueError er rejst.
Men vores sidste input var 9, hvilket er gyldigt, og som et resultat fik vi værdien af “ værdi ”Trykt som 0.1111111111111111
Prøv Endelig Erklæring
Dette er også en valgfri funktion undtagelseshåndtering og kører altid, uanset hvad der sker i undtagelsesbehandlerne.
Det er:
- Uanset om der sker en undtagelse
- Selvom der kaldes et 'retur' i de andre blokke.
- Selv hvis manuskriptet lukkes i de andre blokke
Så hvis vi har en kode, som vi vil køre i alle situationer, er block-endelig vores fyr. Denne blok bruges mest til oprydninger som at lukke filer.
Overvej eksemplet på Python-koden nedenfor
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)
Denne kode forsøger at åbne og læse filen text.txt i den aktuelle mappe. Hvis filen findes, vil vores program udskrive den første linje i filen, så vil vores endelige blok køre og lukke filen.
Sig, at vi har en fil kaldet text.txt i det bibliotek, hvor denne programfil er og indeholder Hej. Hvis vi kører programmet, får vi output
Dette eksempel blev valgt med vilje, fordi jeg ville have os til at løse et lille problem, der kan opstå, når vi lukker filer i den endelige blok.
Hvis filen ikke findes, undtagelsen FileNotFoundError vil blive hævet og variablen åben fil defineres ikke og er ikke et filobjekt. Derfor forsøger at lukke det i den endelige blok en undtagelse Ubundet lokal lokal fejl som er en underklasse af NameError .
Dette siger grundlæggende, at vi prøver at henvise til variablen åben fil inden den er tildelt.
Et lille trick her er at bruge undtagelsesbehandlere inde i den endelige blok.
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)
Hvis vores prøveblok hæver FileNotFoundError, har vi følgende output
Hæv undtagelsen
En god nyhed om Python-undtagelser er, at vi med vilje kan hæve dem. Undtagelser rejses med hæve erklæring .
Hævningserklæringen har følgende syntaks:
raise (ExceptionName((*args: Object)))
Åbn en terminal, og hæv ethvert undtagelsesobjekt fra Python indbyggede undtagelser. For eksempel, hvis vi hæver ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Vi får sporingen:
Så hvorfor er det vigtigt at rejse undtagelser?
- Når du arbejder med brugerdefinerede undtagelser.
- Under fornuftskontrol.
Brugerdefinerede undtagelseskurser
En brugerdefineret undtagelse er en, som du opretter for at håndtere fejl, der er specifikke for dit behov. Tricket er, vi definerer en klasse, der stammer fra objektet Undtagelse , så bruger vi hæveerklæringen til at hæve vores undtagelsesklasse.
Antag, at vi vil kontrollere brugerindgangen og sikre, at inputværdien ikke er negativ (sanity check). Selvfølgelig kunne vi hæve Python-undtagelsen ValueError, men vi vil gerne tilpasse fejlen ved at give den et specifikt og selvforklarende navn som InputIsNegativeError . Men denne undtagelse er ikke en Python-indbygget undtagelse.
Så først opretter vi vores basisklasse, der stammer fra undtagelse.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
Derefter opretter vi vores undtagelsesklasse, der arver basisklassen og håndterer vores specifikke fejl.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Lad os teste dette
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')
Ovenstående kodeanmodning om brugerinput, og kontroller, om den er negativ. Hvis det er sandt, hæver det vores brugerdefinerede undtagelse InputIsNegativeError, som senere fanges i undtagelsessætningen.
Nedenfor er den komplette kode:
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')
Hvis inputværdien er et negativt tal som -1, får vi output:
standard undernetmaske til klasse d
Tjek Python doc for flere detaljer om Python-tilpassede undtagelser.
Ofte stillede spørgsmål
Q # 1) Hvordan håndterer Python en undtagelse?
Svar: Python håndterer undtagelser ved hjælp af prøve undtagen udsagn . Koden, der kan skabe en undtagelse, placeres og udføres i prøv at blokere mens undtagen blok har den kode, der håndterer undtagelserne, hvis der opstår nogen.
Q # 2) Hvad hæver en undtagelse i Python?
Svar: Hver gang Python-tolken støder på en ugyldig kode, rejser den en undtagelse, som er Pythons egen måde at fortælle os, at der skete noget uventet. Vi kan også bevidst hæve undtagelser ved hjælp af hæve erklæring .
Q # 3) Hvordan håndterer Python flere undtagelser?
Svar: Python håndterer flere undtagelser ved hjælp af enten en enkelt undtagen blok eller flere undtagen blokke.
For en enkelt blok sendes undtagelserne som en tuple: undtagen (Exception1, Exception2, .., ExceptionN) og Python kontrollerer for et match fra højre til venstre. I dette tilfælde træffes den samme handling for hver undtagelse.
En anden måde at fange alle undtagelser på er at udelade navnet på undtagelsen efter det undtagne nøgleord.
except: # handle all exceptions here
Den anden måde er at bruge en undtagelsesblok til hver undtagelse:
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å denne måde kan du tage separate handlinger for hver undtagelse.
Spørgsmål nr. 4) Hvorfor er undtagelseshåndtering vigtig i Python?
Svar: Fordelen ved at håndtere undtagelser i Python er, at vi kan skabe robuste, rene og fejlfrie applikationer. Vi vil ikke have vores produktionskode til at gå ned på grund af nogle fejl, så vi håndterer fejlene og holder vores applikation kørende.
Spørgsmål nr. 5) Hvordan ignorerer du en undtagelse i Python?
Svar: For at ignorere en undtagelse i Python skal du bruge passere nøgleord i undtagen blok. Lad os sige, at vi vil ignorere ValueError-undtagelsen. Vi gør det på denne måde:
except ValueError: pass
Medmindre du ved hvad du laver, er det dårlig praksis at ignorere undtagelser. Mindst informer brugeren om alle potentielle fejl.
Konklusion
I denne vejledning dækkede vi: Python Undtagelser, Traceback; hvordan man håndterer undtagelser med Prøve / Undtagen / Andet / Langt om længe blokke, hvordan man Hæve Undtagelser og endelig hvordan man opretter vores egne brugerdefinerede undtagelser.
Tak for læsningen!
=> Besøg her for at lære Python fra bunden.
Anbefalet læsning
- Python-vejledning til begyndere (GRATIS GRATIS Python-træning)
- Python-kontroludtalelser (Python fortsætter, bryder og passerer)
- Python DateTime-tutorial med eksempler
- Python-strengfunktioner
- Python-variabler
- C # Exception Handling Tutorial med kodeeksempler
- Komplet guide til PL SQL-undtagelseshåndtering med eksempler
- Java-undtagelser og undtagelseshåndtering med eksempler