← Назад к вопросам

Зачем нужен try except?

1.0 Junior🔥 291 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Зачем нужен try except?

Try-except — это механизм обработки ошибок (исключений) в Python. Без него программа падает при любой ошибке.

Проблема без try-except

# БЕЗ try-except
def divide(a, b):
    return a / b

result = divide(10, 0)  # ZeroDivisionError: division by zero
print("Программа упала")  # Этот код НЕ выполнится

# Программа прерывается здесь!

Решение с try-except

# С try-except
def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        print("Нельзя делить на ноль!")
        return None

result = divide(10, 0)
print("Программа продолжает работу")  # Это выполнится!

Основные случаи использования

1. Обработка ошибок ввода

def get_user_age():
    try:
        age = int(input("Введите возраст: "))
        if age < 0:
            raise ValueError("Возраст не может быть отрицательным")
        return age
    except ValueError:
        print("Ошибка: введите корректный возраст")
        return get_user_age()  # Попросить снова

age = get_user_age()
print(f"Ваш возраст: {age}")

2. Работа с файлами

def read_config():
    try:
        with open("config.json") as f:
            return json.load(f)
    except FileNotFoundError:
        print("Файл конфига не найден")
        return {}
    except json.JSONDecodeError:
        print("Некорректный JSON")
        return {}

config = read_config()
print(config)

3. Работа с БД

def create_user(name, email):
    try:
        user = User.objects.create(name=name, email=email)
        return user
    except IntegrityError:
        print(f"Пользователь с email {email} уже существует")
        return None
    except Exception as e:
        print(f"Ошибка БД: {e}")
        raise  # Пробросить ошибку дальше

user = create_user("John", "john@example.com")

4. API запросы

import requests

def fetch_user_data(user_id):
    try:
        response = requests.get(
            f"https://api.example.com/users/{user_id}",
            timeout=5
        )
        response.raise_for_status()  # Выбросит HTTPError при 4xx/5xx
        return response.json()
    except requests.exceptions.Timeout:
        print("Запрос истёк по времени")
        return None
    except requests.exceptions.ConnectionError:
        print("Ошибка подключения")
        return None
    except requests.exceptions.HTTPError as e:
        print(f"HTTP ошибка: {e.response.status_code}")
        return None

user_data = fetch_user_data(123)

5. Преобразование типов

def convert_to_int(value):
    try:
        return int(value)
    except ValueError:
        print(f"Не удалось преобразовать '{value}' в int")
        return 0
    except TypeError:
        print(f"Неправильный тип: {type(value)}")
        return 0

print(convert_to_int("123"))     # 123
print(convert_to_int("abc"))     # 0 (ошибка, но программа работает)
print(convert_to_int([1, 2]))    # 0 (ошибка, но программа работает)

Полная структура

try:
    # Основной код
    result = risky_operation()
    print(f"Успех: {result}")
    
except SpecificException as e:
    # Обработка конкретной ошибки
    print(f"Ошибка 1: {e}")
    
except (AnotherError, ThirdError) as e:
    # Обработка нескольких ошибок одновременно
    print(f"Ошибка 2 или 3: {e}")
    
except Exception as e:
    # Обработка ЛЮБОЙ ошибки (но лучше быть конкретнее)
    print(f"Неожиданная ошибка: {e}")
    
else:
    # Выполнится, только если НЕ было исключения
    print("Всё прошло хорошо!")
    
finally:
    # Выполнится в любом случае
    cleanup()

Правила хорошей практики

1. Ловит конкретные исключения

# ПЛОХО — ловит всё
try:
    do_something()
except:
    pass  # Скрываешь все ошибки, даже серьёзные!

# ПЛОХО — слишком широко
try:
    do_something()
except Exception:
    pass  # Все равно ловит всё

# ХОРОШО — конкретные ошибки
try:
    data = json.load(f)
except json.JSONDecodeError:
    print("Некорректный JSON")

2. Не скрывай ошибки

# ПЛОХО — тихо скрывает ошибку
try:
    user = get_user(user_id)
except Exception:
    pass  # Никто не узнает об ошибке!

# ХОРОШО — логируешь или пробрасываешь
try:
    user = get_user(user_id)
except UserNotFound:
    logger.warning(f"User {user_id} not found")
    raise  # Пробрасываю ошибку дальше

3. Не ловит слишком много

# ПЛОХО
try:
    user = get_user(user_id)
    email = user.email
    send_email(email)  # Ошибка здесь не поймается правильно
except:
    print("Ошибка")

# ХОРОШО — разделяй логику
try:
    user = get_user(user_id)
except UserNotFound:
    print("Пользователь не найден")
    return

try:
    send_email(user.email)
except EmailError:
    print("Ошибка отправки письма")

Типы исключений в Python

# Встроенные исключения
ZeroDivisionError      # 1 / 0
ValueError             # int("abc")
TypeError              # "text" + 1
IndexError             # list[999]
KeyError               # dict["missing_key"]
FileNotFoundError      # open("no_file.txt")
TimeoutError           # При истечении времени
KeyboardInterrupt      # Ctrl+C
Exception              # Базовый класс для всех ошибок

Создание собственных исключений

class UserNotFound(Exception):
    """Пользователь не найден"""
    pass

class InvalidEmailError(Exception):
    """Некорректный email"""
    pass

def get_user(user_id):
    user = User.query.get(user_id)
    if user is None:
        raise UserNotFound(f"User {user_id} not found")
    return user

try:
    user = get_user(999)
except UserNotFound as e:
    print(f"Ошибка: {e}")

Благодаря try-except программа

  1. Не падает при ошибках — продолжает работу
  2. Может восстановиться — попробовать снова
  3. Логирует проблемы — понять что случилось
  4. Пользователю комфортно — видит понятные сообщения
  5. Легче отлаживать — понимаешь где ошибка

Итог

Try-except нужен для:

  • Обработки ошибок без падения программы
  • Восстановления после ошибок
  • Логирования проблем
  • Предоставления пользователю полезных сообщений
  • Сохранения состояния приложения