0Pricing
Python Academy · Урок

Вызов и повторный вызов исключений

Используйте raise для сигнализации об ошибках, а повторный вызов — для их передачи выше по стеку.

«Вызов и повторный вызов исключений» — бесплатный урок Python Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Введение

Ключевое слово raise позволяет явно сигнализировать об ошибках. Повторное возбуждение сохраняет исходный контекст ошибки.

Возбуждение встроенного исключения

raise ValueError('message') немедленно возбуждает исключение указанного типа с заданным сообщением.
def divide(a, b):
    if b == 0:
        raise ValueError('Denominator cannot be zero')
    return a / b
try:
    divide(5, 0)
except ValueError as e:
    print(e)

Повторное возбуждение того же исключения

Внутри except инструкция raise без аргумента повторно возбуждает текущее исключение, сохраняя исходную трассировку вызовов.
def process(data):
    try:
        return int(data)
    except ValueError:
        print('logging error')
        raise  # re-raises original
try:
    process('abc')
except ValueError:
    print('caller caught it')

Связывание исключений с помощью from

raise NewError('msg') from original связывает исключения в цепочку. Атрибут exc.__cause__ устанавливается.
try:
    int('abc')
except ValueError as original:
    raise RuntimeError('processing failed') from original

Отключение связывания

raise NewError() from None разрывает цепочку — исходное исключение скрывается в трассировке вызовов.
try:
    int('abc')
except ValueError:
    raise RuntimeError('clean error') from None

Инструкция assert

assert condition, 'message' возбуждает AssertionError, если условие ложно. Используйте её только для инвариантов во время разработки.
def sqrt(x):
    assert x >= 0, f'Input must be non-negative, got {x}'
    return x ** 0.5
try:
    sqrt(-1)
except AssertionError as e:
    print(e)

Условное возбуждение

Защитные конструкции с raise в начале функции делают предварительные условия явными и предотвращают глубокую вложенность.
def process(items):
    if not items:
        raise ValueError('items must not be empty')
    return items[0]
print(process([1, 2, 3]))

Повторное возбуждение и новое исключение

Повторное возбуждение (обычный raise) сохраняет контекст. Новое исключение скрывает его. Используйте связывание, чтобы сохранить видимость обоих исключений.
def outer():
    try:
        inner()
    except ValueError as e:
        raise RuntimeError('outer failed') from e
def inner():
    raise ValueError('inner failed')
try:
    outer()
except RuntimeError as e:
    print(e, e.__cause__)

Исключение в finally

Исключение, возбуждённое в finally, заменяет исходное исключение. Избегайте возбуждения исключений в finally, если это не абсолютно необходимо.
try:
    try:
        raise ValueError('original')
    finally:
        print('finally ran')
except ValueError as e:
    print('caught:', e)

warnings.warn и raise

Используйте warn() для устранимых некритичных ошибок, а raise — для ошибок, которые необходимо обработать. Эти конструкции служат разным целям.
import warnings
def old_func():
    warnings.warn('Deprecated', DeprecationWarning)
    return 42
print(old_func())

Шаблон raise from None

При преобразовании исключений библиотеки в собственные исключения API используйте from None, чтобы не раскрывать внутренние детали.
class DBError(Exception): pass
def query(q):
    try:
        raise ConnectionError('refused')
    except ConnectionError:
        raise DBError('query failed') from None
try:
    query('SELECT 1')
except DBError as e:
    print(e)

Быстрая проверка

Что делает raise без аргумента внутри блока except?

Итоги

raise Type('msg') сигнализирует об ошибках. Обычный raise повторно возбуждает исключение. raise New from Old связывает исключения в цепочку. raise New from None скрывает контекст. assert используется для инвариантов во время разработки.

Продолжайте обучение

Отличная работа! Перейдите к следующему уроку, чтобы продолжить обучение.

Часто задаваемые вопросы

Урок «Вызов и повторный вызов исключений» бесплатный?

Да — полный текст урока «Вызов и повторный вызов исключений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «Вызов и повторный вызов исключений»?

Используйте raise для сигнализации об ошибках, а повторный вызов — для их передачи выше по стеку. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Вызов и повторный вызов исключений»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Разбор исключений
  2. try / except / else / finally
  3. Вызов и повторный вызов исключений
  4. Пользовательские классы исключений
← Назад к Python Academy