🐛 Типичные ошибки

⚡ Топ-3 ошибки

  • Ловить всё подряд через «голый» except: или except Exception:.
  • Ставить общий обработчик Exception перед конкретными.
  • Подавлять ошибки пустым pass, скрывая причину сбоя.

❌ Ошибка 1. «Голый» except

# Неправильно
try:
    number = int(input("Введите число: "))
except:  # перехватывает всё, включая KeyboardInterrupt
    print("Ошибка")

Почему плохо: такой обработчик перехватывает KeyboardInterrupt, SystemExit и другие системные исключения, мешая нормальному завершению программы.

✅ Исправление

# Правильно
try:
    number = int(input("Введите число: "))
except ValueError:
    print("Ошибка: нужно ввести целое число.")

❌ Ошибка 2. Общий Exception перед конкретными

# Неправильно
try:
    result = 10 / 0
except Exception:
    print("Общее исключение")
except ZeroDivisionError:
    print("Деление на ноль")  # этот блок никогда не выполнится

Почему плохо: Python проверяет обработчики сверху вниз. Exception перехватит ZeroDivisionError раньше, чем сработает специфичный обработчик.

✅ Исправление

# Правильно
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Деление на ноль")
except Exception:
    print("Общее исключение")

❌ Ошибка 3. Подавление ошибки пустым pass

# Неправильно
try:
    risky_operation()
except ValueError:
    pass  # ошибка прошла незамеченной

Почему плохо: программа не падает, но и не сообщает о проблеме. Отлаживать такой код крайне сложно.

✅ Исправление

# Правильно
import logging

logging.basicConfig(level=logging.ERROR)

try:
    risky_operation()
except ValueError as e:
    logging.error(f"Ошибка в risky_operation: {e}")
    raise

❌ Ошибка 4. Слишком много кода в блоке try

# Неправильно
try:
    user = load_user()
    order = create_order(user)
    send_email(order)
    save_to_db(order)
except ValueError:
    print("Ошибка значения")  # непонятно, в какой строке ошибка

Почему плохо: в блоке try оказывается слишком много операций, и при перехвате исключения неясно, какая именно строка его вызвала.

✅ Исправление

# Правильно
try:
    user = load_user()
except UserNotFoundError as e:
    logging.error(f"Пользователь не найден: {e}")
else:
    order = create_order(user)
    try:
        send_email(order)
    except EmailError as e:
        logging.warning(f"Письмо не отправлено: {e}")
    save_to_db(order)

❌ Ошибка 5. Игнорирование finally

# Неправильно
file = open("data.txt", "r")
try:
    data = file.read()
except FileNotFoundError:
    print("Файл не найден")
# файл может остаться открытым при ошибке

Почему плохо: если между открытием и чтением возникнет другое исключение, файл не будет закрыт.

✅ Исправление

# Правильно
with open("data.txt", "r", encoding="utf-8") as file:
    data = file.read()

❌ Ошибка 6. Использование assert для проверки ввода

# Неправильно
age = int(input("Введите возраст: "))
assert age >= 18, "Возраст должен быть 18+"

Почему плохо: при запуске с флагом -O assert-инструкции игнорируются, и проверка исчезнет. Для внешних данных используйте raise.

✅ Исправление

# Правильно
age = int(input("Введите возраст: "))
if age < 18:
    raise ValueError("Возраст должен быть 18+")

❌ Ошибка 7. Неправильный уровень логирования

# Неправильно
import logging

logging.basicConfig(level=logging.WARNING)
logging.debug("Начало программы")  # не выведется

Почему плохо: уровень WARNING отбрасывает DEBUG и INFO. Если нужно видеть отладочные сообщения, задайте level=logging.DEBUG.

✅ Исправление

# Правильно
import logging

logging.basicConfig(level=logging.DEBUG)
logging.debug("Начало программы")