python try except python handling exception with examples
Овај водич објашњава руковање изузецима у Питхону помоћу блока Три Екцепт помоћу примера програмирања:
Два типа грешака могу проузроковати нагли заустављање програма Питхон, тј. Синтаксне грешке , и Изузеци . У овом упутству разговараћемо о другом типу грешке (Изузеци) у неколико важних тема.
бесплатне аниме странице за гледање на мрежи
Много ћемо имати користи од руковања изузецима у нашој апликацији, као што су:
- Стварање робусне апликације.
- Стварање чистог кода без грешака.
=> Посетите овде за ексклузивну серију водича за обуку за Питхон
Шта ћете научити:
- Питхон Покушај осим
- Уобичајени изузеци Питхон-а
- Закључак
Питхон Покушај осим
Једна добра вест је да Питхон има велики број уграђених изузетака за хватање грешака у нашем коду. Такође, пружа нам могућност да креирамо прилагођене изузетке када ниједан уграђени изузетак не одговара нашим потребама.
Шта је изузетак
Па, шта је изузетак у Питхону? Једноставно речено, кад год Питхон тумач покуша да изврши неважећи код, он покреће изузетак, а у случајевима када такав изузетак није решен, то нарушава нормалан ток упутстава програма и исписује повратни след.
Направимо неважећи код и видимо како ће Питхон тумач одговорити.
Отворите Питхон љуску и покрените следећи код.
>>> 50/0
Ово је једна од најчешћих грешака у програмирању. Горњи код покушава да подели број педесет од стране 0 (нула). Питхон тумач ово види као неваљану операцију и подиже а ЗероДивисионЕррор , омета програм и исписује повратни след.
То јасно можемо видети ЗероДивисионЕррор је изузетак који је подигнут. То је заиста Питхонов начин да нам каже да није у реду поделити број са нулом. Иако на другим језицима попут ЈаваСцрипт-а, ово није грешка; а питхон строго забрањује ову праксу.
Такође, важно је знати да је ово само објекат за изузетак и да Питхон има уграђено много таквих објеката. Погледајте овог званичника Питхона документација да бисте видели све Питхон уграђене изузетке.
Разумевање Трацебацк-а
Пре него што пређемо на руковање изузецима, мислим да ће вам помоћи да схватимо шта ће се тачно догодити ако се изузеци не обраде и како се Питхон труди да нас обавести о нашој грешци.
Кад год Питхон наиђе на грешку, покреће изузетак. Ако се овим изузетком не поступи, он даје неке информације назване Трацебацк. Па, које информације садржи овај повратни след?
Садржи:
- Порука о грешци која нам говори који је изузетак покренут и шта се догодило пре него што је изузетак покренут.
- Бројеви различитих редова кода који су узроковали ову грешку. До грешке може доћи услед низа позива функција названих а скуп позива о чему ћемо касније овде разговарати.
Иако је помало збуњујуће, обећавамо да ће следећи пример донети више светла нашем разумевању.
Подсетимо се следбеника који је одштампан од дељења 50 са 0 горе, можемо видети да следовање садржи следеће информације:
- Датотека “”: Ово нам говори да је овај код покренут са терминала конзоле.
- ред 1: Ово нам говори да је дошло до грешке у овом броју реда.
- ЗероДивисионЕррор: подела по нула: Говори нам који је изузетак покренут и шта га је изазвало.
Покушајмо са другим примером и можда ћемо видети како а скуп позива Изгледа. Отворите едитор, унесите код испод и сачувајте као трацебацкЕкп .пи
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
Отворите терминал у директоријуму у којем је пронађена и покрените ову датотеку.
python tracebackExp.py
Видећете следећи повратни след:
Горе наведени траг можда делује збуњујуће, али заиста није. Питхонистас су смислили најбољи начин за читање повратног трага, који је из одоздо према горе . Дакле, искористимо ову мудрост да покушамо да разумемо шта овај повратни след нуди.
- Најдоње имамо изузетак који је подигнут и зашто је подигнут.
- Помичући се горе, добивамо име датотеке трацебацкЕкп .пи где је дошло до ове грешке, израчунавање које је изазвало ову грешку цомпуте = нумб / див, функција стек2 и ред броја 6 везе где је извршено ово рачунање.
- Померајући се горе, видимо да је наша функција стацк2 позвана у функцији стецк1 у реду број 3.
- Померајући се на врх, видимо да је функцијски стек1 позван у линији број 11.< модул > говори нам да се датотека извршава.
Уобичајени изузеци Питхон-а
Питхон библиотека дефинише страшно пуно уграђених изузетака. Можете проверити Питхон документацију или позвати уграђену локални () функција као доле:
>>> dir(locals()('__builtins__'))
Нећемо покушати да се позабавимо свим овим изузецима, али видећемо неколико уобичајених изузетака на које ћете вероватно наићи.
# 1) ТипеЕррор
Повисује се када се операција или функција примени на објекат неприкладног типа.
Пример 1
Размотрите доњи програм. Узима дивиденду и делилац, затим израчунава и исписује резултат дељења дивиденде делиоцем.
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()
Од корисника захтевамо вредност дивиденде и делитеља, али заборављамо да вредност низа делиоца пребацимо у цео број. Дакле, на крају имамо да је врста дивиденде цео број ( инт ) а тип делиоца је стринг ( стр ). Тада добијамо ТипеЕррор јер оператор дељења (/) не оперише са низовима.
Можда ће вас занимати да знате да за разлику од Питхона, Јавасцрипт има Типе Цоерцион који у основи претвара један од типова операнда у еквивалентну вредност типа другог операнда када су операнди различитих типова.
# 2) ВалуеЕррор
Ово се покреће када операција или функција прими аргумент који има прави тип, али неприкладну вредност.
Пример 2
Размотрите наш програм у Пример 1 горе.
Ако корисник унесе алфанумеричку вредност за дивиденду попут „3а“, тада ће наш програм подићи изузетак ВалуеЕррор. То је зато што, иако Питхон инт () метода узима било који број или низ и враћа целобројни објекат, вредност низа не би требало да садржи слова или било коју не-нумеричку вредност.
# 3) АттрибутеЕррор
Овај изузетак се покреће приликом додељивања или референцирања атрибута који не постоји.
Пример 3
Размотрите програм у наставку. Узима број и израчунава његов квадратни корен користећи Питхон математички модул
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
Када корисник унесе број, наш програм покушава да користи функцију из математичког модула за израчунавање његовог квадратног корена, али само овде, направили смо грешку. Уместо скрт, грешком смо откуцали скр који не постоји у математичком модулу.
Дакле, покушавали смо да упутимо атрибут скр који не постоји и довели смо до подизања изузетка АттрибутеЕррор. Већина нас пуно погреши у овој врсти. Дакле, нисте сами.
Руковање изузецима помоћу покушаја осим
Као програмер, једна ствар на коју ће већина нас потрошити своје време је писање робусног кода који је еластичан. Код који се не поквари због неких грешака. У Питхону то можемо постићи затварањем наших изјава унутар а покушати - осим изјава.
Питхон Три-Екцепт изјава
Изјава три-осим има следећу структуру:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Приложимо код у трацебацкЕкп .пи унутар изјаве три-осим.
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
Покретање овог кода ће произвести излаз
Овако делује исказ три-осим. Питхон извршава код у блоку три ред 7-8 . Ако није пронађен неважећи код, онда је то код у блоку осим ред 10 се прескаче и извршење се наставља.
Али, ако се пронађе неважећи код, извршење се одмах зауставља у блоку три и проверава да ли се изузетак подиже са оним који смо навели у наредби осим ред 9 . Ако се подудара, тада се извршава и наставља блок осим. Ако се то не догоди, програм ће се прекинути.
Блок покушаја обично садржи код који може довести до изузетка, док блок осим хвата и обрађује изузетак.
Руковање вишеструким изузецима са изузетком
Можемо се носити са вишеструким изузецима било са једним „осим“ или са више „изузетака“. Све зависи од тога како желите да се бавите сваким изузетком.
# 1) Руковање вишеструким изузецима са једним изузетком
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Овај метод се користи када сумњамо да наш код може створити различите изузетке и желимо да предузмемо исту радњу у сваком случају. Дакле, ако тумач Питхон пронађе подударање, тада ће се извршити код написан у блоку осим.
Размотримо пример Питхон кода у наставку
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)
Имамо два могућа изузетка која би се овде могла покренути, ЗероДивисионЕррор и ИндекЕррор . Ако се покрене било који од ових изузетака, тада ће се извршити блок осим.
У коду изнад идк = 3, па идк_ вредност постаје 0 и вредност / идк_ вредност подићи ће ЗероДивисионЕррор
# 2) Руковање вишеструким изузецима са вишеструким изузецима
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Ако бисмо радије желели да сваки изузетак обрадимо одвојено, онда то можете да урадите.
Размотрите пример Питхон кода испод
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
Овде примећујемо да је Екцептион коришћен у последњој наредби осим. То је зато што се изузетак објекта Екцептион подудара са било којим изузетком. Из тог разлога би увек требало да буде последњи, јер ће Питхон престати да проверава друге руковаоце изузецима када се један поклапа.
У горњем коду, идк = 5 , стога арр (идк) подићи ће ИндекЕррор јер идк је већа од дужине списка арр
Такође, нисам сигуран који изузетак је покренула ваша апликација, никада није сигурно да се даље извршава. Због тога имамо тип Изузетак да бисмо ухватили све непредвиђене изузетке. Затим обавештавамо корисника и прекидамо апликацију покретањем истог изузетка.
Испробајте Елсе Статемент
Ово је опционална карактеристика руковања изузетцима и омогућава вам да додате код који желите да покренете када није дошло до грешке. Ако дође до грешке, овај други блок се неће покренути.
Размотрите пример Питхон кода испод, отворите свој едитор и сачувајте код као елсеТри.пи
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
Од корисника добијамо унос и користимо га за поделу 1. Овде имамо два могућа изузетка, неважећи унос корисника који ће проузроковати ВалуеЕррор и а нула (0) што ће изазвати ЗероДивисионЕррор . Наша изјава осим обрађује ове грешке.
Сада желимо да одштампамо вредност вредност . Наш елсе-блоцк осигурава да се штампа само ако се наш три блок изврши без грешке. Ово је важно, јер ако се у нашем блоку покушаја појави грешка, вредност биће недефинисано. Дакле, приступ њему покреће још једну грешку.
Покрените горе наведени код са Питхон елсеТри.пи
Излаз изнад показује да смо за први улаз укуцали 0 и притисните ЕНТЕР. Пошто је наш делилац примио 0, 1 / делилац је подигнут зероДивисионЕррор . Наш други унос је био к који је неважећи за инт (), отуда и изузетак ВалуеЕррор се подиже.
најбољи софтвер за компресовање видео датотека
Али наш последњи унос је био 9 који је важећи и као резултат тога добили смо вредност „ вредност ”Одштампано као 0.1111111111111111
Покушајте коначно Изјава
Ово је такође опционална карактеристика руковања изузетком и увек ће се покретати без обзира на то шта се догоди у руковаоцима изузетцима.
То је:
- Без обзира да ли долази до изузетка или не
- Чак и ако се у осталим блоковима позове „повратак“.
- Чак и ако се скрипта затвори у осталим блоковима
Дакле, ако имамо код који желимо да покренемо у свим ситуацијама, коначно-блоцк је наш тип. Овај блок се углавном користи за чишћења попут затварања датотека.
Размотрите пример Питхон кода испод
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)
Овај код покушава да отвори и прочита датотеку тект.ткт у свом тренутном директоријуму. Ако датотека постоји, тада ће наш програм исписати први ред датотеке, а затим ће се покренути наш коначни блок и затворити датотеку.
Рецимо да имамо датотеку која се зове тект.ткт у директоријуму где се налази ова програмска датотека и садржи Хелло. Ако покренемо програм, имаћемо излаз
Овај пример је намерно изабран јер сам желео да решимо мали проблем који се може појавити приликом затварања датотека у коначно-блоку.
Ако датотека не постоји, изузетак ФилеНотФоундЕррор биће подигнута и променљива отворен филе неће бити дефинисано и неће бити објекат датотеке. Стога ће покушај затварања у коначно-блок створити изузетак УнбоундЛоцалЕррор што је подкласа од НамеЕррор .
Ово у основи говори да покушавамо да референцирамо променљиву отворен филе пре него што је додељен.
Мали трик овде је употреба руковалаца изузецима унутар коначно-блока.
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)
Ако наш покушај блокирања покаже ФилеНотФоундЕррор, тада ћемо добити следећи излаз
Подигните изузетак
Једна добра вест о изузецима Питхона је та што их можемо намерно подићи. Изузеци се подижу код подићи изјаву .
Изјава о повишици има следећу синтаксу:
raise (ExceptionName((*args: Object)))
Отворите терминал и подигните било који изузетак из Питхон уграђени изузеци. На пример, ако подигнемо ЗероДивисионЕррор:
>>> raise ZeroDivisionError('Can't divide by zero')
Добићемо повратни след:
Па, зашто је важно подизати изузетке?
- Када радите са прилагођеним изузецима.
- Током провере здравственог стања.
Прилагођене класе изузетака
Прилагођени изузетак је онај који креирате да бисте обрадили грешке специфичне за ваше потребе. Трик је у томе што дефинишемо класу која потиче од објекта Изузетак , тада користимо изјаву раисе да повисимо нашу класу изузетака.
Претпоставимо да желимо да проверимо унос корисника и да се уверимо да улазна вредност није негативна (провера исправности). Наравно, могли бисмо да покренемо Питхон изузетак ВалуеЕррор, али волећемо да прилагодимо грешку дајући јој специфично и саморазумљиво име попут ИнпутИсНегативеЕррор . Али овај изузетак није изузетак уграђен у Питхон.
Дакле, прво креирамо нашу основну класу која ће проистећи из изузетка.
class CustomError(Exception): 'Base class exception for all exceptions of this module' pass
Затим креирамо нашу класу изузетка која ће наследити основну класу и баратаће нашом специфичном грешком.
class InputIsNegativeError(CustomError): '''Raised when User enters a negative value''' pass
Да тестирамо ово
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')
Горњи захтев за код за унос од стране корисника и проверите да ли је негативан. Ако је тачно, покреће наш прилагођени изузетак ИнпутИсНегативеЕррор који је касније ухваћен у наредби осим.
Испод је комплетан код:
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')
Ако је улазна вредност негативан број попут -1, тада ћемо добити излаз:
Погледајте Питхон доц за више детаља о Питхон прилагођеним изузецима.
Често постављана питања
П # 1) Како Питхон обрађује изузетак?
Одговор: Питхон обрађује изузетке користећи изјава о покушају осим . Код који може створити изузетак поставља се и извршава у покушајте блокирати док осим блока садржи код који ће обрадити изузетке ако се појаве.
П # 2) Шта покреће изузетак у Питхону?
Одговор: Кад год Питхон интерпретер наиђе на неважећи код, он покреће изузетак, што је Питхонов начин да нам каже да се догодило нешто неочекивано. Такође можемо намерно да правимо изузетке користећи подићи изјаву .
П # 3) Како Питхон обрађује вишеструке изузетке?
Одговор: Питхон обрађује вишеструке изузетке користећи или један осим блока или вишеструки осим блокова.
За један блок, изузеци се преносе као скуп: осим (Изузетак1, Изузетак2, .., ИзузетакН) и Питхон проверава подударање с десна на лево. У овом случају се предузима иста радња за сваки изузетак.
Други начин да се ухвате сви изузеци је изостављање имена изузетка након кључне речи осим.
except: # handle all exceptions here
Други начин је коришћење блока осим за сваки изузетак:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
На овај начин можете предузети засебне радње за сваки изузетак.
П # 4) Зашто је руковање изузецима важно у Питхону?
Одговор: Предност руковања изузецима у Питхону је та што можемо створити робусне, чисте и без грешака апликације. Нећемо желети да се наш производни код сруши због неких грешака, зато се бавимо грешкама и одржавамо нашу апликацију активном.
П # 5) Како игнорисати изузетак у Питхону?
Одговор: Да бисте занемарили изузетак у Питхону, користите проћи кључна реч у блоку осим. Рецимо да желимо да занемаримо изузетак ВалуеЕррор. Учинићемо то на следећи начин:
except ValueError: pass
Ако не знате шта радите, лоша је пракса игнорисати изузетке. Обавестите корисника бар о свим потенцијалним грешкама.
Закључак
У овом упутству смо обрадили: Питхон Екцептионс, Трацебацк; како се носити са изузецима са Покушати / Осим / Елсе / Коначно блокови, како да Подићи Изузеци и коначно како да креирамо сопствене прилагођене изузетке.
Хвала за читање!
=> Посетите овде да бисте научили Питхон од нуле.
Препоручено читање
- Питхон Водич за почетнике (Практични БЕСПЛАТНИ Питхон тренинг)
- Изјаве о контроли Питхона (Питхон Цонтинуе, Бреак анд Пасс)
- Водич за Питхон ДатеТиме са примерима
- Питхон Стринг функције
- Питхон променљиве
- Водич за руковање изузецима за Ц # са примерима кода
- Комплетан водич за руковање изузецима ПЛ СКЛ-а са примерима
- Јава изузеци и руковање изузецима са примерима