as e: объект ошибки в переменной
Обработчик узнаёт больше, если взять ошибку в переменную: except ValueError as e даёт тип, сообщение и аргументы исключения.
Редакция Питоники
До сих пор запасные планы были слепыми: except сообщал «не число», но не говорил, что именно Python пытался разобрать и почему отказался. А ведь в traceback эта информация была: invalid literal for int() with base 10: 'двенадцать'. Хорошая новость — её не обязательно терять: исключение можно поймать не только для реакции, но и для разбора. Для этого у except есть вторая форма — с переменной.
Берём объект ошибки: as e
Запись except ValueError as e: делает две вещи: ловит ValueError и кладёт объект ошибки в переменную e. Объект — это не строка, а полноценное значение со своими данными: типом, сообщением, аргументами.
try:
n = int('двенадцать')
except ValueError as e:
print('Тип:', type(e).__name__)
print('Сообщение:', e)
print('Аргументы:', e.args)
Тип: ValueError
Сообщение: invalid literal for int() with base 10: 'двенадцать'
Аргументы: ("invalid literal for int() with base 10: 'двенадцать'",)Три способа заглянуть в пойманную ошибку. type(e).__name__ — имя типа в виде строки: ValueError. Печать самого e даёт сообщение — тот же текст, что завершал traceback в первом уроке. e.args — кортеж аргументов, с которыми ошибка была создана; у нашего ValueError он из одного элемента. Для первых двух задач достаточно печати e — но имя типа пригождается, когда один обработчик обслуживает несколько типов и нужно понять, кто именно прилетел.
Сообщение ошибки: у каждого типа своё
Сообщение — самое ценное в объекте: это человеческое описание причины. Печать e в запасном плане делает его информативным:
try:
n = int('двенадцать')
except ValueError as e:
print('Не разобрали:', e)
Не разобрали: invalid literal for int() with base 10: 'двенадцать'
Теперь план Б не врёт обобщениями — он показывает, с каким значением разбор провалился. Сравните с «не разобрали» из прошлого урока: разница как между «заявка отклонена» и «заявка отклонена: не указана дата».
У разных типов сообщения разные по форме. KeyError вместо длинной фразы печатает сам недостающий ключ — в кавычках:
d = {'Анна': 5}
try:
print(d['Пётр'])
except KeyError as e:
print('Тип:', type(e).__name__)
print('Сообщение:', e)
Тип: KeyError Сообщение: 'Пётр'
Сообщение KeyError выглядит коротко: ключ в кавычках. Python печатает его так же, как в traceback первого урока, — это договорённость именно этого типа. Отсюда практический вывод: не полагайтесь на форму сообщения, полагайтесь на тип. Тип говорит, какая авария случилась; сообщение — детали для человека.
Лог в цикле: каждую аварию — в протокол
Соберём рабочую схему: суммарный разбор списка, где сбойные строки не роняют отчёт, а попадают в протокол с сообщением ошибки.
values = ['4', 'x', '9']
total = 0
for v in values:
try:
total += int(v)
except ValueError as e:
print('пропустил', repr(v), '-', e)
print('Итого:', total)
пропустил 'x' - invalid literal for int() with base 10: 'x' Итого: 13
Протокол говорит всё: какую строку пропустили (repr показывает её в кавычках, чтобы пустые строки были видны) и почему именно. Четвёрка и девятка вошли в сумму, икс — в протокол. Такая строка в логе экономит минуты расследования: видно и значение-виновник, и формулировку ошибки.
Имя переменной выбираете вы
e в записи as e — не зарезервированное слово, а обычное имя, которое придумывает автор кода. Курс по циклам любит короткие имена в заголовках циклов — здесь так же: e, err, ex. Смысл от имени не меняется:
try:
n = int('abc')
except ValueError as err:
print(type(err).__name__, '-', err)
ValueError - invalid literal for int() with base 10: 'abc'
err напечатал то же, что печатал бы e: имя переменной — только ярлык для объекта ошибки. В одной программе стоит выбрать одно имя и держаться его, как выбирают единый стиль для переменных цикла.
e живёт только внутри except
Переменная из as e живёт только внутри except: на выходе из блока Python удаляет её сам. Проверим, что будет, если обратиться к e после блока:
try:
n = int('двенадцать')
except ValueError as e:
print('поймали:', e)
print(e)
поймали: invalid literal for int() with base 10: 'двенадцать'
Traceback (most recent call last):
File "app.py", line 5, in <module>
print(e)
^
NameError: name 'e' is not definedПервая печать сработала — внутри блока переменная была жива. Печать после блока упала с NameError: имя больше не существует. Python делает это специально, чтобы объекты ошибок не болтались в программе дольше необходимого. Правило простое: разбираем ошибку внутри except; что нужно на будущее — сохраняем в свою переменную, например message = str(e), ещё внутри блока.
try:
n = int('двенадцать')
except ValueError as e:
print(e.upper())
Traceback (most recent call last):
File "app.py", line 2, in <module>
n = int('двенадцать')
~~~^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'двенадцать'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "app.py", line 4, in <module>
print(e.upper())
^^^^^^^
AttributeError: 'ValueError' object has no attribute 'upper'Шпаргалка по объекту ошибки
| Выражение | Что даёт | Пример значения |
|---|---|---|
| print(e) или str(e) | Сообщение ошибки | invalid literal for int() with base 10: 'x' |
| type(e).__name__ | Имя типа строкой | ValueError |
| e.args | Кортеж аргументов | ("invalid literal ...",) |
| message = str(e) | Сохранение сообщения на будущее | работает только внутри except |
| e.upper() | Ошибка: объект не строка | AttributeError |
Мы научились не только ловить ошибку, но и забирать её данные: тип для ветвления, сообщение для протокола. Дальше — два хвоста try, которые расширяют конструкцию: else выполнится при успехе, а finally — при любом исходе. А цепочка обработчиков из четвёртого урока теперь может писать разные сообщения для разных типов.
Сначала предскажи ответ в голове — это главный навык программиста.
try:
n = int('42')
except ValueError as e:
print('ошибка:', e)
print('готово')
try:
n = int('семь')
except ValueError as e:
print(type(e).__name__)
print(e)
words = ['3', 'нет']
total = 0
for w in words:
try:
total += int(w)
except ValueError as e:
print('мимо:', e)
print(total)
1. Что делает запись except ValueError as e?
2. Как получить имя типа ошибки строкой?
3. Что напечатает print(e) для пойманного KeyError('Пётр')?
4. Что случится с переменной e после выхода из блока except?
5. Что вернёт e.args у ValueError('сообщение')?
6. Почему e.upper() падает с AttributeError?
7. Можно ли вместо e использовать другое имя — err?
8. Зачем печатать сообщение ошибки в запасном плане?
Дан список values = ['3', 'кот']. Посчитай сумму разобранных чисел, а сбойные строки пропускай с протоколом: «отклонено: <сообщение ошибки>». В конце напечатай сумму.
Что значит as e в except python?
Это сохранение пойманного объекта ошибки в переменную: except ValueError as e кладёт исключение в e. Внутри блока доступны тип (type(e).__name__), сообщение (print(e)) и аргументы (e.args). Имя e — произвольное: подойдёт err или ex.
Урок 6: else и finallyКак напечатать текст ошибки python?
Взять объект ошибки через as и напечатать его: except ValueError as e: print(e). print сам приводит объект к строке и печатает сообщение — тот же текст, что в последней строке traceback.
Сколько живёт переменная e из except?
Только внутри блока except: на выходе Python удаляет её, и обращение даёт NameError: name 'e' is not defined. Если сообщение нужно дальше по программе, сохраните его внутри блока: message = str(e).
Можно ли вызвать строковые методы у объекта ошибки?
Нет, напрямую нельзя: e.upper() упадёт с AttributeError, потому что объект исключения — не строка. Сначала приведите: str(e).upper(). Печать print(e) работает без приведения.
Чем полезно e.args?
Это кортеж аргументов, с которыми ошибка была создана: у ValueError('сообщение') args равен ('сообщение',). Пригодится, когда сообщение нужно как отдельное значение без строкового представления всего объекта.
Понравился урок? Сошлитесь на него
«Переменная из as e живёт только внутри except: на выходе из блока Python удаляет её сам.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Исключения · Урок 3
except ValueError: ловим конкретный тип ошибки
Уточняем обработчик: except ValueError ловит только свой тип ошибок. Почему голый except прячет опечатки и как ValueError ведёт себя у int и list.remove.
Исключения · Урок 4
Несколько except: разные ошибки — разные реакции
Цепочка except-блоков: ValueError — один план, ZeroDivisionError — другой. Порядок обработчиков, правило одного обработчика и кортеж типов.
Исключения · Урок 6
else и finally: два хвоста try
Два хвоста try: else работает при успехе, finally — при любом исходе. Разбираем порядок try, except, else, finally и место каждого блока.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
aiogram · Урок 9
Обработка ошибок в телеграм-боте: try/except, лимиты и логи
Учим бот переживать ошибки: try/except в хендлерах, лимиты Telegram с RetryAfter, модуль logging вместо print и перезапуск polling после падения.
обработка ошибок pythonошибки телеграм бота
Flask · Урок 11
Обработка ошибок во Flask: свои страницы 404 и 500
Одиннадцатый урок курса Flask: гость опечатался в адресе — и видит английскую заглушку без вашего меню. Учимся отдавать свои страницы 404 и 500 через @app.errorhandler, честно отвечать abort(404), когда записи нет, и проверять статусы через test_client.
flask обработка ошибок 404flask страница ошибки 500
Исключения · Урок 2
try и except: ловим ошибку и не падаем
Первый запасной план: try держит рискованный код, except — что делать, если он упал. Прыжки, пропуски и try внутри цикла — на живом коде.
try except pythonpython try except