python try except python handling exception with examples
Tento kurz vysvětluje zpracování výjimek v Pythonu pomocí bloku Try Except pomocí příkladů programování:
Dva typy chyb mohou způsobit, že se program Pythonu náhle zastaví, tj. Chyby syntaxe , a Výjimky . V tomto kurzu se budeme zabývat druhým typem chyby (Výjimky) v rámci několika důležitých témat.
Při zpracování výjimek v naší aplikaci budeme mít velký užitek, například:
- Vytváření robustní aplikace.
- Vytváření čistého a bezchybného kódu.
=> Navštivte zde exkluzivní sérii výukových kurzů pro Python
Co se naučíte:
- Python Vyzkoušejte kromě
- Běžné výjimky Pythonu
- Závěr
Python Vyzkoušejte kromě
Jednou dobrou zprávou je, že Python má velký počet vestavěných výjimek pro zachycení chyb v našem kódu. Také nám dává příležitost vytvořit vlastní výjimky, když žádná z integrovaných výjimek nevyhovuje našim potřebám.
Co je to výjimka
Co je tedy v Pythonu výjimkou? Zjednodušeně řečeno, kdykoli se interpret Pythonu pokusí provést neplatný kód, vyvolá výjimku a v případech, kdy taková výjimka není zpracována, naruší normální tok pokynů programu a vytiskne zpětné sledování.
Vytvořme neplatný kód a podívejme se, jak zareaguje tlumočník Pythonu.
Otevřete prostředí Pythonu a spusťte následující kód.
>>> 50/0
Toto je jedna z nejčastějších chyb v programování. Výše uvedený kód se pokusí číslo rozdělit padesátka podle 0 (nula). Interpret Pythonu to považuje za neplatnou operaci a vyvolá a ZeroDivisionError , přeruší program a vytiskne zpětné sledování.
To jasně vidíme ZeroDivisionError je výjimka, která byla vznesena. Je to skutečně Pythonův vlastní způsob, jak nám říci, že není skvělé dělit číslo nulou. I když v jiných jazycích, jako je JavaScript, nejde o chybu; a python tuto praxi přísně zakazuje.
Je také důležité vědět, že se jedná pouze o objekt výjimky a Python má mnoho takových objektů zabudovaných. Podívejte se na tohoto úředníka Pythonu dokumentace zobrazit všechny vestavěné výjimky Pythonu.
Pochopení Traceback
Než se pustíme do zpracování výjimek, myslím, že to pomůže pochopit, co přesně se stane, pokud výjimky nebudou zpracovány a jak se Python snaží nás informovat o naší chybě.
Kdykoli Python narazí na chybu, vyvolá výjimku. Pokud tato výjimka není zpracována, vytvoří některé informace zvané Traceback. Jaké informace tedy tento zpětný sled obsahuje?
Obsahuje:
- Chybová zpráva, která nám říká, jaká výjimka byla vyvolána a co se stalo před touto výjimkou.
- Různá čísla řádků kódu, která způsobila tuto chybu. Chyba může být způsobena posloupností volání funkcí zvaných a zásobník volání o kterém budeme diskutovat později zde.
I když je to trochu matoucí, slibujeme, že další příklad přinese více světla našemu porozumění.
Připomeňme si zpětné trasování, které bylo vytištěno z dělení 50 na 0 výše, vidíme, že zpětné sledování obsahuje následující informace:
- Soubor „“: Toto nám říká, že tento kód byl spuštěn z terminálu konzoly.
- řádek 1: Toto nám říká, že k chybě došlo v tomto čísle řádku.
- ZeroDivisionError: dělení nula: Říká nám, jaká výjimka byla vznesena a co ji způsobilo.
Zkusme další příklad a možná uvidíme, jak zásobník volání vypadá jako. Otevřete editor, zadejte níže uvedený kód a uložte jako 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
Otevřete terminál v adresáři, kde je tento soubor nalezen, a spusťte jej.
python tracebackExp.py
Uvidíte následující zpětné sledování:
Výše uvedený zpětný sled se může zdát matoucí, ale ve skutečnosti tomu tak není. Pythonistas přišel s nejlepším způsobem, jak číst traceback, který je z zdola nahoru . Pojďme se tedy pomocí této moudrosti pokusit pochopit, co tato zpětná vazba nabízí.
- V dolní části dostaneme výjimku, která byla zvýšena a proč byla zvýšena.
- Pohybem nahoru získáme název souboru tracebackExp .py kde k této chybě došlo, výpočet, který tuto chybu způsobil, compute = numb / div, funkce stack2 a řádek čísla linky 6, kde byl tento výpočet proveden.
- Pohybem nahoru vidíme, že naše funkce stack2 byla volána ve funkci stack1 v řádku číslo 3.
- Pohybující se na vrchol vidíme, že funkce stack1 byla volána na řádku číslo 11.< modul > říká, že se provádí soubor.
Běžné výjimky Pythonu
Knihovna Pythonu definuje spoustu zabudovaných výjimek. Můžete zkontrolovat dokumentaci Pythonu nebo zavolat vestavěný místní () funkce níže:
>>> dir(locals()('__builtins__'))
Nebudeme se snažit řešit všechny tyto výjimky, ale uvidíme několik běžných výjimek, na které pravděpodobně narazíte.
# 1) TypeError
Vyvolá se při použití operace nebo funkce na objekt nevhodného typu.
Příklad 1
Zvažte níže uvedený program. Přijme dividendu a dělitele, poté vypočítá a vytiskne výsledek dělení dividendy dělitelem.
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()
Požadujeme od uživatele hodnotu dividendy a dělitele, ale zapomeneme vložit hodnotu řetězce dělitele na celé číslo. Takže skončíme tím, že typ dividendy bude celé číslo ( int ) a typ dělitele je řetězec ( p ). Pak dostaneme TypeError protože operátor dělení (/) nefunguje na řetězcích.
Mohlo by vás zajímat, že na rozdíl od Pythonu má Javascript Type Coercion, který v zásadě převádí jeden z typů operandů na ekvivalentní hodnotu typu druhého operandu, když jsou operandy různých typů.
# 2) ValueError
Toto je vyvoláno, když operace nebo funkce obdrží argument, který má správný typ, ale nevhodnou hodnotu.
Příklad 2
Zvažte náš program v Příklad 1 výše.
Pokud uživatel zadá alfanumerickou hodnotu dividendy jako „3a“, náš program zvýší výjimku ValueError. Je to proto, že i když Python int () metoda převezme jakékoli číslo nebo řetězec a vrátí celočíselný objekt, hodnota řetězce by neměla obsahovat písmena ani žádnou jinou než číselnou hodnotu.
# 3) AttributeError
Tato výjimka je vyvolána při přiřazování nebo odkazování na atribut, který neexistuje.
Příklad 3
Zvažte níže uvedený program. Přijme číslo a vypočítá druhou odmocninu pomocí Matematický modul Pythonu
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
Když uživatel zadá číslo, náš program se pokusí použít funkci z matematického modulu k výpočtu jeho druhé odmocniny, ale právě zde jsme udělali chybu. Namísto sqrt jsme omylem zadali sqr, který v matematickém modulu neexistuje.
Snažili jsme se tedy odkazovat na atribut sqr, který neexistuje, a vedl k vyvolání výjimky AttributeError. Většina z nás dělá tento druh chyby hodně. Takže nejste sami.
Zpracování výjimek pomocí Try Except
Jako programátor jedna věc, kterou většina z nás stráví čas, je psaní robustního kódu, který je odolný. Kód, který se nerozbije kvůli některým chybám. V Pythonu toho můžeme dosáhnout uzavřením našich prohlášení uvnitř a Snaž se - až na tvrzení.
Příkaz Python Try-Except
Příkaz try-except má následující strukturu:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Uzavřeme kód tracebackExp .py uvnitř příkazu 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
Spuštěním tohoto kódu vyprodukujete výstup
Takto funguje příkaz try-except. Python provede kód v bloku try řádek 7-8 . Pokud není nalezen žádný neplatný kód, pak kód v bloku kromě řádek 10 je přeskočeno a provádění pokračuje.
Pokud je však nalezen neplatný kód, pak se spuštění okamžitě zastaví v bloku try a zkontroluje, zda se vyvolaná výjimka shoduje s tím, který jsme zadali v příkazu výjimkou řádek 9 . Pokud se shoduje, provede se blok s výjimkou a pokračuje. Pokud se tak nestane, program se přeruší.
Try-block obvykle obsahuje kód, který může vyvolat výjimku, zatímco výjimkový blok výjimku zachytí a zpracuje.
Zpracování více výjimek s výjimkou
Můžeme zpracovat několik výjimek s jedinou „výjimkou“ nebo několika „výjimkami“. Vše záleží na tom, jak chcete zvládnout každou výjimku.
# 1) Zpracování více výjimek s jedinou výjimkou
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Tato metoda se používá, když máme podezření, že náš kód může vyvolat různé výjimky a chceme v každém případě provést stejnou akci. Pokud tedy interpret Pythonu najde shodu, provede se kód zapsaný v bloku kromě.
Podívejme se níže na ukázkový kód Pythonu
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)
Máme dvě možné výjimky, které by zde mohly být vzneseny, ZeroDivisionError a IndexError . Pokud je vyvolána některá z těchto výjimek, bude proveden blok kromě.
V kódu výše, idx = 3, takže idx_ hodnota se stane 0 a hodnota / idx_ hodnota zvýší ZeroDivisionError
# 2) Zpracování více výjimek s více výjimkami
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Pokud bychom raději chtěli každou výjimku zpracovat zvlášť, pak to můžete udělat.
Zvažte níže uvedený ukázkový kód Pythonu
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
Všimli jsme si zde, že v posledním příkazu kromě byla použita výjimka. Je to proto, že objekt výjimky Exception odpovídá jakékoli výjimce. Z tohoto důvodu by to mělo být vždy poslední, protože Python přestane kontrolovat další obslužné rutiny výjimek, jakmile se jedna shoduje.
V kódu výše, idx = 5 , proto arr (idx) zvýší IndexError protože idx je větší než délka seznamu přílet
Také si nejste jisti, jakou výjimku vaše aplikace vyvolala, nikdy není bezpečné pokračovat v provádění. Proto máme typ Exception, který zachytí všechny nepředvídané výjimky. Poté informujeme uživatele a přerušíme aplikaci zvýšením stejné výjimky.
Zkuste jiný příkaz
Tohle je volitelná funkce zpracování výjimek a umožňuje vám přidat kód, který chcete spustit, když nedojde k žádným chybám. Pokud dojde k chybě, tento jiný blok se nespustí.
Zvažte níže uvedený příklad Pythonu, otevřete editor a uložte kód jako else Try.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
Dostaneme vstup od uživatele a použijeme jej k rozdělení 1. Máme zde dvě možné výjimky, neplatný vstup uživatele, který způsobí ValueError a a nula (0) což způsobí ZeroDivisionError . Naše prohlášení s výjimkou zpracovává tyto chyby.
Nyní chceme vytisknout hodnotu hodnota . Náš else-block zajišťuje, že se vytiskne, pouze pokud se náš try blok spustí bez chyby. To je důležité, protože pokud dojde k chybě v našem try-blocku, hodnota bude nedefinováno. Přístup k němu tedy vyvolá další chybu.
Spusťte výše uvedený kód s Python else Try.py
Výstup výše ukazuje, že pro první vstup jsme zadali 0 a stiskněte ENTER. Vzhledem k tomu, že náš dělitel obdržel 0, 1 / dělitel zvýšil zeroDivisionError . Náš druhý vstup byl k, což je neplatné pro int (), proto výjimka ValueError je zvednutý.
Ale náš poslední vstup byl 9, který je platný, a ve výsledku jsme dostali hodnotu „ hodnota ”Vytištěno jako 0.1111111111111111
Zkuste konečně prohlášení
To je také volitelná funkce zpracování výjimek a vždy se spustí bez ohledu na to, co se stane v obslužných rutinách výjimek.
To je:
- Zda dojde k výjimce
- I když je v ostatních blocích volán „návrat“.
- I když je skript ukončen v ostatních blocích
Takže pokud máme kód, který chceme spustit za všech situací, konečně je block náš chlap. Tento blok se většinou používá k vyčištění, jako je zavírání souborů.
Zvažte níže uvedený ukázkový kód Pythonu
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)
Tento kód se pokusí otevřít a přečíst soubor text.txt v jeho aktuálním adresáři. Pokud soubor existuje, náš program vytiskne první řádek souboru, poté se spustí náš konečný blok a soubor zavře.
Řekněme, že máme soubor s názvem text.txt v adresáři, kde je tento programový soubor a obsahuje Hello. Pokud spustíme program, budeme mít výstup
Tento příklad byl vybrán záměrně, protože jsem chtěl, abychom řešili malý problém, který může nastat při zavírání souborů v bloku finally.
Pokud soubor neexistuje, výjimka FileNotFoundError bude zvýšena a proměnná otevřít soubor nebude definován a nebude objektem souboru. Pokus o uzavření v bloku finally tedy vyvolá výjimku UnboundLocalError což je podtřída Chyba názvu .
To v podstatě říká, že se snažíme odkazovat na proměnnou otevřít soubor před přiřazením.
nejlepší převodník z youtube na mp3 zdarma
Malý trik je použít obslužné rutiny výjimek uvnitř bloku finally.
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)
Pokud náš try-block vyvolá FileNotFoundError, budeme mít následující výstup
Zvýšit výjimku
Jedna dobrá zpráva o výjimkách Pythonu je, že je můžeme záměrně zvýšit. Výjimky jsou vyvolány pomocí zvýšit prohlášení .
Příkaz raise má následující syntaxi:
raise (ExceptionName((*args: Object)))
Otevřete terminál a zvedněte jakýkoli objekt výjimky z Integrované výjimky Pythonu. Například, pokud zvýšíme ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Dostaneme zpětný odkaz:
Proč je tedy důležité vznášet výjimky?
- Při práci s vlastními výjimkami.
- Během kontrol zdravého rozumu.
Třídy vlastních výjimek
Vlastní výjimka je ta, kterou vytvoříte pro zpracování chyb, které jsou specifické pro vaši potřebu. Trik spočívá v tom, že definujeme třídu, která je odvozena od objektu Výjimka , pak použijeme příkaz raise ke zvýšení třídy výjimek.
Předpokládejme, že chceme zkontrolovat vstup uživatele a ujistit se, že vstupní hodnota není záporná (kontrola zdravého rozumu). Samozřejmě bychom mohli zvýšit výjimku Pythonu ValueError, ale rádi bychom chybu přizpůsobili tím, že jí dáme konkrétní a samozřejmý název jako InputIsNegativeError . Ale tato výjimka není vestavěná výjimka Pythonu.
Nejprve tedy vytvoříme naši základní třídu, která bude odvozena z výjimky.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
Pak vytvoříme naši třídu výjimek, která zdědí základní třídu a bude zpracovávat naši konkrétní chybu.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Zkusme to
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')
Výše uvedený požadavek na kód pro vstup uživatele a zkontrolujte, zda je negativní. Pokud je to pravda, vyvolá to naši vlastní výjimku InputIsNegativeError, která je později zachycena v příkazu výjimkou.
Níže je uveden kompletní kód:
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')
Pokud je vstupní hodnota záporné číslo jako -1, pak budeme mít výstup:
Podívejte se na Python doc pro více informací o vlastních výjimkách Pythonu.
Často kladené otázky
Otázka č. 1) Jak Python zpracovává výjimku?
Odpovědět: Python zpracovává výjimky pomocí příkaz try-except . Kód, který může vyvolat výjimku, je umístěn a spuštěn v zkuste blokovat zatímco kromě bloku obsahuje kód, který zpracuje výjimky, pokud nějaké nastanou.
Otázka 2) Co vyvolává výjimku v Pythonu?
Odpovědět: Kdykoli překladač Pythonu narazí na neplatný kód, vyvolá výjimku, což je Pythonův vlastní způsob, jak nám říct, že se stalo něco neočekávaného. Můžeme také záměrně vyvolat výjimky pomocí zvýšit prohlášení .
Otázka č. 3) Jak Python zpracovává více výjimek?
Odpovědět: Python zpracovává více výjimek pomocí jediného bloku kromě bloku nebo několika bloků kromě bloku.
U jednoho bloku jsou výjimky předávány jako n-tice: až na (Exception1, Exception2, .., ExceptionN) a Python kontroluje shodu zprava doleva. V tomto případě se pro každou výjimku provede stejná akce.
Dalším způsobem, jak zachytit všechny výjimky, je vynechat název výjimky za klíčovým slovem kromě.
except: # handle all exceptions here
Druhým způsobem je použít blok výjimky pro každou výjimku:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
Tímto způsobem můžete provádět samostatné akce pro každou výjimku.
Otázka č. 4) Proč je zpracování výjimek v Pythonu důležité?
Odpovědět: Výhodou zpracování výjimek v Pythonu je, že můžeme vytvářet robustní, čisté a bezchybné aplikace. Nebudeme chtít, aby se náš výrobní kód zhroutil kvůli některým chybám, takže chyby řešíme a udržujeme naši aplikaci v provozu.
Otázka č. 5) Jak ignorujete výjimku v Pythonu?
Odpovědět: Chcete-li ignorovat výjimku v Pythonu, použijte složit klíčové slovo v bloku kromě. Řekněme, že chceme ignorovat výjimku ValueError. Uděláme to takto:
except ValueError: pass
Pokud nevíte, co děláte, je špatnou praxí ignorovat výjimky. Alespoň informujte uživatele o všech potenciálních chybách.
Závěr
V tomto tutoriálu jsme se zabývali: Python Exceptions, Traceback; jak zacházet s výjimkami pomocí Snaž se / Až na / Jiný / Konečně bloky, jak na to Vyzdvihnout Výjimky a nakonec, jak vytvořit vlastní vlastní výjimky.
Děkuji za přečtení!
=> Navštivte zde a dozvíte se Python od nuly.
Doporučené čtení
- Výukový program pro Python pro začátečníky (praktické školení v Pythonu ZDARMA)
- Kontrolní příkazy Pythonu (Python Continue, Break and Pass)
- Výukový program Python DateTime s příklady
- Funkce řetězce Python
- Proměnné Pythonu
- Výukový program pro zpracování výjimek C # s příklady kódu
- Kompletní průvodce zpracováním výjimek PL SQL s příklady
- Výjimky Java a zpracování výjimek s příklady