python try except python handling exception with examples
Този урок обяснява обработката на изключения в Python с помощта на блока Try Освен с помощта на примери за програмиране:
Два вида грешки могат да доведат до внезапно спиране на програма на Python, т.е. Синтаксични грешки , и Изключения . В този урок ще обсъждаме втория тип грешка (Изключения) по няколко важни теми.
Ще се възползваме много от обработката на изключения в нашето приложение като:
- Създаване на стабилно приложение.
- Създаване на чист код без грешки.
=> Посетете тук за ексклузивната серия уроци за обучение по Python
Какво ще научите:
- Python Опитайте с изключение
- Често срещани изключения на Python
- Заключение
Python Опитайте с изключение
Една добра новина е, че Python има голям брой вградени изключения за улавяне на грешки в нашия код. Освен това ни дава възможност да създаваме персонализирани изключения, когато нито едно от вградените изключения не отговаря на нашите нужди.
Какво е изключение
И така, какво е изключение в Python? Е, с прости думи, когато интерпретаторът на Python се опитва да изпълни невалиден код, той създава изключение и в случаите, когато такова изключение не се обработва, то нарушава нормалния поток от инструкциите на програмата и отпечатва обратна връзка.
Нека създадем невалиден код и да видим как интерпретаторът на Python ще реагира.
Отворете обвивката на Python и изпълнете следния код.
>>> 50/0
Това е една от най-често срещаните грешки в програмирането. Горният код се опитва да раздели числото петдесет от 0 (нула). Интерпретаторът на Python вижда това като невалидна операция и повдига a ZeroDivisionError , нарушава програмата и отпечатва обратна връзка.
Виждаме ясно това ZeroDivisionError е изключението, което беше повдигнато. Това наистина е начинът, по който Python ни казва, че не е готино да разделяме число на нула. Въпреки че на други езици като JavaScript, това не е грешка; и python строго забранява тази практика.
Също така е важно да знаете, че това е просто обект на изключение и Python има вградени много такива обекти. Вижте този служител на Python документация за да видите всички Python вградени изключения.
Разбиране на Traceback
Преди да се заемем с обработката на изключения, мисля, че ще помогне да се разбере какво точно ще се случи, ако изключенията не бъдат обработени и как Python прави всичко възможно да ни информира за нашата грешка.
Всеки път, когато Python срещне грешка, той поражда изключение. Ако това изключение не бъде обработено, то създава информация, наречена Traceback. И така, каква информация съдържа това проследяване?
Съдържа:
- Съобщението за грешка, което ни казва какво изключение е повдигнато и какво се е случило преди това изключение е било повдигнато.
- Различните номера на редове на кода, които са причинили тази грешка. Грешка може да бъде причинена от поредица от извиквания на функции, наречена a стек повиквания които ще обсъдим по-късно тук.
Въпреки че е малко объркващо, обещаваме, че следващият пример ще внесе повече светлина в нашето разбиране.
Спомнете си проследяването, което беше отпечатано от разделянето на 50 на 0 по-горе, можем да видим, че проследяването съдържа следната информация:
- Файл „”: Това ни казва, че този код е стартиран от конзолен терминал.
- ред 1: Това ни казва, че грешката е възникнала в този номер на ред.
- ZeroDivisionError: разделяне на нула: Той ни казва какво изключение е повдигнато и какво го е причинило.
Нека опитаме друг пример и може би ще видим как a стек повиквания изглежда като. Отворете редактор, въведете кода по-долу и запазете като tracebackExp .py
c ++ двойно свързан списък
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
Ще видите следното проследяване:
Горното проследяване може да изглежда объркващо, но всъщност не е така. Pythonistas измислиха най-добрия начин за четене на проследяване, който е от отдолу нагоре . И така, нека използваме тази мъдрост, за да се опитаме да разберем какво може да предложи това проследяване.
- Най-отдолу получаваме изключението, което е повдигнато и защо е повдигнато.
- Придвижвайки се нагоре, получаваме името на файла tracebackExp .py, където е възникнала тази грешка, изчислението, което е причинило тази грешка, изчислява = numb / div, функцията стек2, и ред номер 6 на връзката, където е извършено това изчисление.
- Придвижвайки се нагоре, виждаме, че нашата функция stack2 е била извикана във функцията stack1 в ред номер 3.
- Придвижвайки се до най-горното, виждаме, че функцията стек1 е извикана в ред номер 11.< модул > казва ни, че файлът е този, който се изпълнява.
Често срещани изключения на Python
Библиотеката на Python дефинира страшно много вградени изключения. Можете да проверите документацията на Python или да се обадите на вградената местни () функция както по-долу:
>>> dir(locals()('__builtins__'))
Няма да се опитваме да обърнем внимание на всички тези изключения, но ще видим няколко често срещани изключения, които вероятно ще срещнете.
# 1) TypeError
То се повишава, когато операция или функция е приложена към обект от неподходящ тип.
Пример 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()
Искаме от потребителя стойността на дивидента и делителя, но забравяме да прехвърлим низовата стойност на делителя в цяло число. И така, стигаме до това, че типът на дивидента е цяло число ( инт ) и типът на делителя е низ ( стр ). След това получаваме TypeError тъй като операторът на разделяне (/) не работи върху низове.
Може да ви заинтересува да знаете, че за разлика от Python, Javascript има Type Coercion, който основно преобразува един от типовете на операнда в еквивалентна стойност на типа на другия операнд, когато операндите са от различни типове.
# 2) ValueError
Това се повдига, когато операция или функция получи аргумент, който има правилния тип, но неподходяща стойност.
Пример 2
Помислете за нашата програма в Пример 1 по-горе.
Ако потребителят въведе буквено-цифрова стойност за дивидента като ‘3a’, тогава нашата програма ще повиши изключението ValueError. Това е така, въпреки че Python int () метод приема всяко число или низ и връща цяло число обект, стойността на низа не трябва да съдържа букви или някаква нечислова стойност.
# 3) AttributeError
Това изключение се повдига, докато се присвоява или препраща към атрибут, който не съществува.
Пример 3
Помислете за програмата по-долу. Той взема число и изчислява квадратния си корен, използвайки Модул по математика на 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
Когато потребител въведе число, нашата програма се опитва да използва функция от математическия модул, за да изчисли неговия квадратен корен, но точно това тук, ние направихме грешка. Вместо sqrt, погрешно набрахме sqr, който не съществува в математическия модул.
И така, ние се опитвахме да препращаме към атрибут sqr, който не съществува, и доведохме до повдигане на изключението AttributeError. Повечето от нас много грешат този вид. И така, не сте сами.
Обработка на изключения с Опитайте с изключение
Като програмист едно нещо, за което повечето от нас ще отделят време, е писането на стабилен код, който е устойчив. Код, който не се счупи поради някои грешки. В Python можем да постигнем това, като затворим нашите изявления в a опитвам - с изключение изявление.
Изявление на Python Try-Osim
Операторът try-osim има следната структура:
try: #your code goes here except '''Specify exception type(s) here''': #handle exception here
Нека приложим кода в tracebackExp .py вътре в инструкция try-Osim.
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
Изпълнението на този код ще доведе до изхода
Ето как работи операторът try-osim. Python изпълнява кода в блока try ред 7-8 . Ако не бъде намерен невалиден код, тогава кодът в блока освен ред 10 се пропуска и изпълнението продължава.
Но ако бъде открит невалиден код, изпълнението незабавно спира в блока try и проверява дали повдигнатото изключение съвпада с това, което сме предоставили в инструкцията за изключение ред 9 . Ако съвпада, тогава блокът изключение се изпълнява и продължава. Ако не стане, тогава програмата ще прекъсне.
Опитният блок обикновено съдържа кода, който може да предизвика изключение, докато блокът освен, улавя и обработва изключението.
Обработка на множество изключения с
Можем да обработваме множество изключения с еднократно „изключение“ или множество „изключения“. Всичко зависи от това как искате да се справите с всяко изключение.
# 1) Обработка на множество изключения с едно изключение
try: #your code goes here except(Exception1(, Exception2(,...ExceptionN)))): #handle exception here
Този метод се използва, когато подозираме, че нашият код може да създаде различни изключения и искаме да предприемем едно и също действие във всеки случай. Така че, ако интерпретаторът на Python намери съвпадение, тогава кодът, написан в блока освен, ще се изпълни.
Нека разгледаме примерния код на Python по-долу
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)
Имаме две възможни изключения, които биха могли да бъдат повдигнати тук, ZeroDivisionError и IndexError . Ако някое от тези изключения бъде повдигнато, тогава блокът освен ще бъде изпълнен.
В горния код idx = 3, така че idx_ стойност става 0 и стойност / idx_ стойност ще повиши ZeroDivisionError
# 2) Обработка на множество изключения с множество изключения
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Ако предпочитаме да се справим с всяко изключение поотделно, тогава ето как можете да го направите.
Помислете за примерния код на Python по-долу
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
Тук забелязваме, че в последното изявление с изключение е използвано изключение. Това е така, защото изключението на обекта за изключение съвпада с всяко изключение. Поради тази причина тя винаги трябва да е последна, тъй като Python ще спре да проверява други манипулатори на изключения, след като някой съвпадне.
В горния код, idx = 5 , следователно arr (idx) ще вдигне IndexError защото idx е по-голяма от дължината на списъка обр
Също така, не съм сигурен какво изключение е повдигнато от вашето приложение, никога не е безопасно да продължи изпълнението. Ето защо имаме типа Изключение, за да уловим всички непредвидени изключения. След това информираме потребителя и прекъсваме приложението, като повдигаме същото изключение.
Опитайте Else Statement
Това е незадължителна функция на обработка на изключения и ви позволява да добавите код, който искате да стартирате, когато не са възникнали грешки. Ако възникне грешка, този блок else няма да се изпълни.
Помислете за примерния код на Python по-долу, отворете редактора си и запазете кода като 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
Получаваме входни данни от потребителя и го използваме за разделяне на 1. Тук има две възможни изключения, невалидно въвеждане от потребителя, което ще причини ValueError и а нула (0) което ще предизвика ZeroDivisionError . Нашата инструкция освен се справя с тези грешки.
Сега искаме да разпечатаме стойността на стойност . Нашият else-block гарантира, че е отпечатан само ако нашият try блок се изпълнява без грешка. Това е важно, защото ако възникне грешка в нашия блок за опит, стойност ще бъде неопределено. Така че достъпът до него ще доведе до друга грешка.
Стартирайте горния код с Python elseTry.py
Резултатът по-горе показва, че за първия вход въведохме 0 и натиснете ENTER. Тъй като нашият делител получи 0, 1 / делител се повиши zeroDivisionError . Вторият ни вход беше k, което е невалидно за инт (), оттук и изключението ValueError се повдига.
кой тип тест се използва, за да се провери дали всички програми в дадено приложение работят заедно правилно?
Но последното ни въвеждане беше 9, което е валидно и в резултат получихме стойността на „ стойност ”Отпечатан като 0.1111111111111111
Опитайте окончателно изявление
Това също е незадължителна функция на обработка на изключения и винаги ще се изпълнява, независимо какво се случва в обработчиците на изключения.
Това е:
- Дали възниква изключение или не
- Дори ако в другите блокове се извика „return“.
- Дори ако скриптът е затворен в останалите блокове
Така че, ако имаме код, който искаме да изпълним във всички ситуации, накрая-block е нашият човек. Този блок се използва най-вече за почиствания като затваряне на файлове.
Помислете за примерния код на Python по-долу
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)
Този код се опитва да отвори и прочете файла text.txt в текущата си директория. Ако файлът съществува, тогава нашата програма ще отпечата първия ред на файла, след което нашият окончателен блок ще се стартира и ще затвори файла.
Да кажем, че имаме файл, наречен text.txt в директорията, където е този програмен файл и съдържа Hello. Ако стартираме програмата, ще имаме изхода
Този пример беше избран умишлено, защото исках да се справим с малък проблем, който може да възникне при затваряне на файлове в окончателния блок.
Ако файлът не съществува, изключението FileNotFoundError ще се повиши и променливата отвори файл няма да бъде дефиниран и няма да бъде файлов обект. Следователно, опитът да го затворите в блока окончателно ще доведе до изключение UnboundLocalError което е подклас на NameError .
Това основно казва, че се опитваме да се позовем на променливата отвори файл преди да е назначен.
Малък трик тук е да се използват манипулатори на изключения в блока 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)
Ако нашият try-block повдигне FileNotFoundError, тогава ще имаме следния изход
Повишаване на изключение
Една добра новина за изключенията на Python е, че можем умишлено да ги повишим. Изключенията се извеждат с рейз изявление .
Операторът на повишение има следния синтаксис:
raise (ExceptionName((*args: Object)))
Отворете терминал и повдигнете всеки обект на изключение от Вградени в Python изключения. Например, ако вдигнем ZeroDivisionError:
>>> raise ZeroDivisionError('Can't divide by zero')
Ще получим проследяване:
И така, защо е важно да се правят изключения?
- При работа с персонализирани изключения.
- По време на проверки за вменяемост.
Персонализирани класове за изключения
Персонализирано изключение е това, което създавате за обработка на грешки, специфични за вашите нужди. Номерът е, че дефинираме клас, който произлиза от обекта Изключение , тогава използваме инструкцията за повишаване, за да повишим нашия клас на изключение.
Да предположим, че искаме да проверим въведеното от потребителя и да се уверим, че стойността на входа не е отрицателна (проверка на здравословното състояние). Разбира се, бихме могли да повдигнем изключението на Python ValueError, но ще искаме да персонализираме грешката, като й дадем конкретно и обяснително име като InputIsNegativeError . Но това изключение не е вградено в Python изключение.
Така че първо, ние създаваме нашия основен клас, който ще произтича от изключение.
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')
Горната заявка за код за въвеждане от потребителя и проверете дали е отрицателна. Ако е вярно, това повдига нашето персонализирано изключение InputIsNegativeError, което по-късно се улавя в оператора изключение.
По-долу е даден пълният код:
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, тогава ще имаме изхода:
Вижте Python doc за повече подробности относно персонализираните изключения на Python.
често задавани въпроси
В # 1) Как Python се справя с изключение?
Отговор: Python обработва изключения, използвайки изявление try-Osim . Кодът, който може да предизвика изключение, се поставя и изпълнява в опитайте да блокирате докато с изключение на блок съдържа код, който ще обработва изключенията, ако възникнат такива.
В # 2) Какво е повдигане на изключение в Python?
Отговор: Всеки път, когато интерпретаторът на Python срещне невалиден код, той поражда изключение, което е собственият начин на Python да ни каже, че се е случило нещо неочаквано. Можем също така умишлено да създадем изключения, като използваме рейз изявление .
В # 3) Как Python се справя с множество изключения?
Отговор: Python обработва множество изключения, използвайки или единичен, освен блок, или множество освен блокове.
За един блок изключенията се предават като кортеж: с изключение (Изключение1, Изключение2, .., ИзключениеN) и Python проверява за съвпадение отдясно наляво. В този случай се предприемат едни и същи действия за всяко изключение.
Друг начин за улавяне на всички изключения е да се остави името на изключението след ключовата дума освен.
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) Защо обработката на изключения е важна в Python?
Отговор: Ползата от обработката на изключения в Python е, че можем да създадем стабилни, чисти и без грешки приложения. Няма да искаме производственият ни код да се срива поради някои грешки, затова се справяме с грешките и поддържаме приложението си работещо.
В # 5) Как се игнорира изключение в Python?
Отговор: За да игнорирате изключение в Python, използвайте мине ключова дума в блока с изключение. Да приемем, че искаме да игнорираме изключението ValueError. Ще го направим по този начин:
except ValueError: pass
Освен ако не знаете какво правите, е лоша практика да игнорирате изключенията. Информирайте поне потребителя за всички потенциални грешки.
Заключение
В този урок разгледахме: Изключения на Python, Traceback; как да се справя с изключенията с Опитвам / С изключение / Иначе / Накрая блокове, как да Повишаване Изключения и накрая как да създадем свои собствени персонализирани изключения.
Благодаря за четенето!
=> Посетете тук, за да научите Python от нулата.
Препоръчително четене
- Урок за Python за начинаещи (практически БЕЗПЛАТНО обучение за Python)
- Изявления за контрол на Python (Python Continue, Break and Pass)
- Урок за Python DateTime с примери
- Функции на низовете на Python
- Променливи на Python
- C # Урок за обработка на изключения с примери за кодове
- Пълно ръководство за PL SQL обработка на изключения с примери
- Изключения на Java и обработка на изключения с примери