Руководство по исключению Python
View more Tutorials:
Для начала посмотрим следующий иллюстрированный пример:
В данном примере есть код с ошибкой по причине деления на 0. Из-за деления на 0 происходит исключение: ZeroDivisionError
В данном примере есть код с ошибкой по причине деления на 0. Из-за деления на 0 происходит исключение: ZeroDivisionError
helloExceptionExample.py
print ("Three") # This division no problem. value = 10 / 2 print ("Two") # This division no problem. value = 10 / 1 print ("One") d = 0 # This division has problem, divided by 0. # An error has occurred here. value = 10 / d # And the following code will not be executed. print ("Let's go!")
Результат запуска примера:
Вы можете увидеть уведомление ошибки на экране Console, уведомление ошибки очень понятное, на какой строке кода это произошло.
Вы можете увидеть уведомление ошибки на экране Console, уведомление ошибки очень понятное, на какой строке кода это произошло.

Посмотрим потом программы на изображении ниже.
- Программа запущена как обычно с шагов (1),(2) до (6)
- В шаге (7) происходит проблема при делении на 0. Программа завершается.
- В шаге (8) код не был выполнен.

Мы изменим код в примере выше.
helloCatchException.py
print ("Three") value = 10 / 2 print ("Two") value = 10 / 1 print ("One") d = 0 try : # Это деление имеет проблему, деление на 0. # Здесь происходит ошибка (ZeroDivisionError). value = 10 / d print ("value = ", value) except ZeroDivisionError as e : print ("Error: ", str(e) ) print ("Ignore to continue ...") print ("Let's go!")
И результаты запуска примера:

Мы объясним используя иллюстрацию ниже о потоке программы.
- Шаги (1)-(6) совершенно нормальны.
- Исключение происходит в шаге (7), проблема при делении на 0.
- Сразу он перепрыгивает на выполнение команды в блоке except, шаг (8) пропускается.
- Шаги (9), (10) выполняются.
- Шаг (11) выполняется.

Это модель иерархии исключений в Python.
- Самый высший класс это BaseException
- Прямыми подклассами являются Exception и KeyboardInterrupt, ..
Готовые Exception в Python обычно получены из (derived) BaseException (Расширены из BaseException). В то время как exception пользвателя (программиста) должны быть унаследованы из класса Exception или из его подкласса.

Мы напишем класс exception унаследованный из класса Exception.
See more:

Функция checkAge для проверки возраста, если возраст меньше 18 или больше 40, выбрасывается исключение.
ageexception.py
# Python 3.x class AgeException(Exception): def __init__(self, msg, age ): super().__init__(msg) self.age = age class TooYoungException(AgeException): def __init__(self, msg, age): super().__init__(msg, age) class TooOldException(AgeException): def __init__(self, msg, age): super().__init__(msg, age) # Функция проверки возраста, может выбросить исключение. def checkAge(age): if (age < 18) : # Если возраст менее 18, выбросится исключение. # Фукнция завершится здесь. raise TooYoungException("Age " + str(age) + " too young", age) elif (age > 40) : # Если возраст старше 40, выбросится исключение. # Фукнция завершится здесь. raise TooOldException("Age " + str(age) + " too old", age); # Если возраст в рамках 18-40. # Этот код будет выполнен. print ("Age " + str(age) + " OK!");
Пример:
tryExceptDemo1.py
import ageexception from ageexception import AgeException from ageexception import TooYoungException from ageexception import TooOldException print ("Start Recruiting ...") age = 11 print ("Check your Age ", age) try : ageexception.checkAge(age) print ("You pass!") except TooYoungException as e : print("You are too young, not pass!") print("Cause message: ", str(e) ) print("Invalid age: ", e.age) except TooOldException as e : print ("You are too old, not pass!") print ("Cause message: ", str(e) ) print("Invalid age: ", e.age)
Запуск примера:

В примере ниже, мы обработаем все собранные исключения на уровне выше. На уровне выше обработаются все эти исключения и унаследованные исключения.
tryExceptDemo2.py
import ageexception from ageexception import AgeException from ageexception import TooYoungException from ageexception import TooOldException print ("Start Recruiting ...") age = 51 print ("Check your Age ", age) try : ageexception.checkAge(age) print ("You pass!") except AgeException as e : print("You are not pass!") print("type(e): ", type(e) ) print("Cause message: ", str(e) ) print("Invalid age: ", e.age)
Запуск примера:

Выше мы ознакомились с обработкой исключений через блок try-except. Полная обработка исключения использует try-except-finally. Блок finally всегда выполняется, несмотря не то, происходит исключение в блоке try или нет.
try - except - finally
try : # Сделать что-то здесь. except Exception1 as e : # Сделать что-то здесь. except Exception2 as e : # Сделать что-то здесь. finally : # Блок finally всегда выполняется. # Сделать что-то здесь.
Пример:
tryExceptFinallyDemo.py
def toInteger(text) : try : print ("-- Begin parse text: ", text) # Исключение может быть выброшено здесь (ValueError). value = int(text) return value except ValueError as e : # В случае 'text' не является числом. # Блок 'except' будет выполнен. print ("ValueError message: ", str(e)) print ("type(e): ", type(e)) # Возвращает 0 если появляется ошибка ValueError. return 0 finally : print ("-- End parse text: " + text) text = "001234A2" value = toInteger(text) print ("Value= ", value)
Запуск примера:

Это поток программы. Блок finally всегда выполняется.

Команда pass
Если ничего не хотите обрабатывать в блоке 'except' или 'finally' вы можете использовать команду 'pass' (pass statement). Команда pass ничего не делает, она похожа на команду null.
passStatementExample.py
print ("Three") try : value = 10 / 0; except Exception as e: pass print ("Two") print ("One") print ("Let's go")

При обработке исключения вы можете словить это исключение и обработать или перевыбросить (rethrow) его наружу.
reRaiseExceptionDemo1.py
def checkScore(score) : if score < 0 or score > 100: raise Exception("Invalid Score " + str(score) ) def checkPlayer(name, score): try : checkScore(score) except Exception as e : print ("Something invalid with player: ",name, ' >> ', str(e) ) # re throw exception. raise # ------------------------------------------ checkPlayer("Tran", 101)

Например, словить инсключение и перевыбросить (rethrow) другое исключение.
reRaiseExceptionDemo2.py
def checkScore(score) : if score < 0 or score > 100: raise Exception("Invalid Score " + str(score) ) def checkPlayer(name, score): try : checkScore(score) except Exception as e : print ("Something invalid with player: ",name, ' >> ', str(e) ) # throw new exception. raise Exception("Something invalid with player: "+ name + " >> "+ str(e)) # ------------------------------------------ checkPlayer("Tran", 101)

Python позволяет ловить иключение, и выбрасывать новое исключение, новое исключение может хранить информацию начального исключения, в который вы можете иметь доступ через атрибут __cause__.
try : # Сделать что-то здесь.... except Exception as e : raise OtherException("Message...") from e
Смотрите полный пример:
wrapExceptionDemo.py
# Python 3.x: # Исключение пола. class GenderException(Exception): def __init__(self, msg): super().__init__(msg) # Исключение языка. class LanguageException(Exception): def __init__(self, msg): super().__init__(msg) class PersonException(Exception): def __init__(self, msg): super().__init__(msg) # Эта функция может выбросить GenderException. def checkGender(gender): if gender != 'Female' : raise GenderException("Accept female only") # Эта функция может выбросить LanguageException. def checkLanguage(language): if language != 'English' : raise LanguageException("Accept english language only") def checkPerson(name, gender, language): try : # Может выбросить GenderException. checkGender(gender) # Может выбросить LanguageException. checkLanguage(language) except Exception as e: # Ловит exception и выбрасывает другие исключения. # Новое исключение имеет информацию __cause__ = e. raise PersonException(name + " does not pass") from e # -------------------------------------------------------- try : checkPerson("Nguyen", "Female", "Vietnamese") except PersonException as e: print ("Error message: ", str(e) ) # GenderException или LanguageException cause = e.__cause__ print ('e.__cause__: ', repr(cause)) print ("type(cause): " , type(cause) ) print (" ------------------ ") if type(cause) is GenderException : print ("Gender exception: ", cause) elif type(cause) is LanguageException: print ("Language exception: ", cause)
