BaseException
Все исключения наследуются от BaseException. Атрибуты и методы:
| Элемент | Описание |
|---|---|
args | Кортеж аргументов, переданных конструктору |
with_traceback(tb) | Возвращает исключение с заданным traceback |
add_note(note) | Добавляет заметку (Python 3.11+) |
__notes__ | Список заметок |
__cause__ | Причина, заданная через raise ... from ... |
__context__ | Исключение, при обработке которого возникло текущее |
__traceback__ | Объект traceback |
__suppress_context__ | Скрывать ли контекст при выводе |
try: int("abc")except ValueError as e: print(e.args) print(type(e).__name__) print(str(e)) print(repr(e))Иерархия встроенных исключений
BaseException├── BaseExceptionGroup├── GeneratorExit├── KeyboardInterrupt├── SystemExit└── Exception ├── ArithmeticError │ ├── FloatingPointError │ ├── OverflowError │ └── ZeroDivisionError ├── AssertionError ├── AttributeError ├── BufferError ├── EOFError ├── ExceptionGroup ├── ImportError │ └── ModuleNotFoundError ├── LookupError │ ├── IndexError │ └── KeyError ├── MemoryError ├── NameError │ └── UnboundLocalError ├── OSError │ ├── BlockingIOError │ ├── ChildProcessError │ ├── ConnectionError │ │ ├── BrokenPipeError │ │ ├── ConnectionAbortedError │ │ ├── ConnectionRefusedError │ │ └── ConnectionResetError │ ├── FileExistsError │ ├── FileNotFoundError │ ├── InterruptedError │ ├── IsADirectoryError │ ├── NotADirectoryError │ ├── PermissionError │ ├── ProcessLookupError │ └── TimeoutError ├── ReferenceError ├── RuntimeError │ ├── NotImplementedError │ ├── PythonFinalizationError │ └── RecursionError ├── StopAsyncIteration ├── StopIteration ├── SyntaxError │ └── IndentationError │ └── TabError ├── SystemError ├── TypeError ├── ValueError │ └── UnicodeError │ ├── UnicodeDecodeError │ ├── UnicodeEncodeError │ └── UnicodeTranslateError └── Warning ├── BytesWarning ├── DeprecationWarning ├── EncodingWarning ├── FutureWarning ├── ImportWarning ├── PendingDeprecationWarning ├── ResourceWarning ├── RuntimeWarning ├── SyntaxWarning ├── UnicodeWarning └── UserWarningИсключение PythonFinalizationError появилось в Python 3.13. Состав иерархии может немного отличаться между версиями.
Самые частые исключения
| Исключение | Когда возникает | Пример |
|---|---|---|
ValueError | Правильный тип, но недопустимое значение | int("abc") |
TypeError | Операция применена к неподходящему типу | "a" + 1 |
KeyError | Нет ключа в словаре | {}["x"] |
IndexError | Индекс вне диапазона | [][0] |
AttributeError | Нет атрибута | None.x |
NameError | Имя не определено | print(zzz) |
ZeroDivisionError | Деление на ноль | 1 / 0 |
FileNotFoundError | Нет файла | open("no.txt") |
ImportError | Ошибка импорта | from os import zzz |
StopIteration | Итератор исчерпан | next(iter([])) |
RecursionError | Превышена глубина рекурсии | бесконечная рекурсия |
NotImplementedError | Метод должен быть переопределён | в абстрактных методах |
AssertionError | Не выполнено assert | assert 1 == 2 |
KeyboardInterrupt | Нажато Ctrl+C | |
SystemExit | Вызван sys.exit() |
Перехват
Порядок блоков except важен: первым срабатывает подходящий:
def safe_div(a, b): try: return a / b except ZeroDivisionError: return None except TypeError as e: print("типы:", e) return None except Exception as e: print("прочее:", e) raise else: print("успешно") finally: print("готово")print(safe_div(1, 0))print(safe_div(1, "a"))Базовые классы перехватывают потомков:
try: [][0]except LookupError as e: print(type(e).__name__)Цепочки исключений
class ConfigError(Exception): passdef load(path): try: return open(path).read() except OSError as e: raise ConfigError(f"не удалось прочитать {path}") from etry: load("missing.txt")except ConfigError as e: print(e) print(repr(e.__cause__))raise X from Yзадаёт явную причинуraise X from Noneскрывает контекстraiseбез аргументов повторно выбрасывает текущее исключение
Собственные исключения
class AppError(Exception): passclass ValidationError(AppError): def __init__(self, field, message): super().__init__(f"{field}: {message}") self.field = field self.message = messagetry: raise ValidationError("email", "некорректный адрес")except AppError as e: print(e) print(e.field)Хорошая практика — иметь один базовый класс исключений для проекта.
Заметки к исключениям
try: try: int("x") except ValueError as e: e.add_note("при разборе параметра port") raiseexcept ValueError as e: print(e.__notes__)ExceptionGroup и except*
Python 3.11 добавил возможность собирать несколько исключений в группу:
def run(): raise ExceptionGroup("несколько ошибок", [ ValueError("a"), TypeError("b"), ValueError("c"), ])try: run()except* ValueError as eg: print("ValueError:", [str(e) for e in eg.exceptions])except* TypeError as eg: print("TypeError:", [str(e) for e in eg.exceptions])Группы нужны прежде всего для асинхронного кода, где несколько задач могут завершиться ошибкой одновременно.
Атрибуты отдельных исключений
try: open("missing.txt")except FileNotFoundError as e: print(e.errno) print(e.strerror) print(e.filename)try: "é".encode("ascii")except UnicodeEncodeError as e: print(e.encoding, e.reason, e.start, e.end)try: import nothing_hereexcept ImportError as e: print(e.name)suppress
Если исключение нужно просто проигнорировать:
from contextlib import suppressimport oswith suppress(FileNotFoundError): os.remove("temp.txt")Предупреждения
Warning и его потомки — исключения-предупреждения, которыми управляет модуль warnings:
import warningswarnings.warn("функция устарела", DeprecationWarning, stacklevel=2)warnings.simplefilter("error")Задания
- Напишите иерархию исключений для библиотеки работы с платежами.
- Реализуйте функцию, которая оборачивает системные ошибки файловых операций в собственное исключение, сохраняя причину.
- Соберите ошибки валидации формы в
ExceptionGroupи обработайте черезexcept*.
