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

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

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

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

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

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

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

# Правильно
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. Ручная склейка путей

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

folder = "data"
filename = "users.txt"
path = folder + "/" + filename  # сломается в Windows

Почему плохо: разделители путей различаются в Windows и Unix-подобных системах. Ручная склейка приводит к ошибкам.

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

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

path = os.path.join("data", "users.txt")

❌ Ошибка 4. Подавление ошибки пустым 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

❌ Ошибка 5. Слишком много кода в блоке 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)

❌ Ошибка 6. os.mkdir для вложенных директорий

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

os.mkdir("parent/child")  # FileNotFoundError, если parent не существует

Почему плохо: os.mkdir создаёт только одну директорию и не создаёт родительские.

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

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

os.makedirs("parent/child", exist_ok=True)

❌ Ошибка 7. Обращение к sys.argv[1] без проверки

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

directory = sys.argv[1]  # IndexError, если аргумент не передан
print(os.listdir(directory))

Почему плохо: если пользователь не передал аргумент, программа упадёт с IndexError.

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

# Правильно
import sys
import os

if len(sys.argv) != 2:
    print("Использование: python script.py <директория>")
    sys.exit(1)

directory = sys.argv[1]
if not os.path.isdir(directory):
    print(f"Директория '{directory}' не существует.")
    sys.exit(1)

print(os.listdir(directory))

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

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

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

Почему плохо: уровень WARNING отбрасывает DEBUG и INFO.

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

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

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