5 самых распространённых ошибок в Python и способы их исправления

Python дружелюбен к новичкам, но ошибки неизбежны. Независимо от уровня опыта, большинство программистов регулярно сталкиваются с одними и теми же типами исключений. Понимание корня проблемы и стандартных приёмов отладки ускорит исправление и повысит качество кода.
Важно: эта статья ориентирована на практическое применение — краткие определения, реальные примеры и чеклисты для разработчика, ревьюера и тестировщика.
Что такое исключение в двух строках
Исключение — это сигнал интерпретатору о том, что во время выполнения программы произошла нестандартная ситуация. Некоторые исключения возникают ещё при разборе кода (например, SyntaxError), другие — во время выполнения (RuntimeError, AttributeError и т.д.).
Ошибка IndentationError — несоответствие отступов
Описание: IndentationError возникает, когда уровни отступов в блоке кода неконсистентны или нарушают синтаксические правила Python. В Python блоки определяются отступами, поэтому одинаковая вложенность обязана поддерживаться.
Когда встречается: чаще всего у новичков, при копировании кода между редакторами или при смешивании пробелов и табуляций.
Пример ошибки:
for i in range(5):
print(i)
Использование/польза IDE: современные редакторы отмечают неправильные отступы прямо в редакторе и могут автоматически конвертировать табы в пробелы.
Исправление:
for i in range(5):
print(i)
Подводные камни:
- Смешение табов и пробелов: визуально кажется правильным, но интерпретатор ругается.
- Нулевой отступ внутри вложенного блока — тоже ошибка.
Советы:
- Настройте редактор на использование 4 пробелов для отступа.
- Включите видимость пробелов/таба в редакторе.
- Перед коммитом прогоняйте линтер (flake8, pylint) и автоформаттер (black).
Примеры команд для проверки и исправления:
# Проверка стилевых ошибок
flake8 path/to/project
# Автоформатирование
black path/to/project
Критерии приёмки:
- Все файлы проходят flake8 без ошибок отступов.
- CI не принимает коммиты с табуляцией (если политика проекта — пробелы).
Ошибка SyntaxError — нарушение синтаксиса
Описание: SyntaxError возникает на этапе парсинга, когда код не соответствует грамматике Python. Программа не запустится до исправления синтаксиса.
Типичные причины:
- Забыл двоеточие после заголовка блока (if, for, def, class).
- Неправильные или опечатанные ключевые слова (esle вместо else).
- Незакрытые скобки или кавычки.
- Неправильное использование операторов.
Примеры распространённых ошибок:
if x > 0
print(x)
# или
for i in range(5):
print(i
Диагностика:
- Сообщение интерпретатора обычно даёт строку и позицию ошибки — это отправная точка.
- Иногда реальная ошибка находится на предыдущей строке (например, незакрытая кавычка), поэтому читайте контекст.
Как исправлять:
- Сначала исправьте синтаксис, затем запустите тесты.
- Используйте статический анализатор и синтаксическую подсветку в IDE.
Когда подсказка может ввести в заблуждение: при сложных выражениях Python может указать позицию, где парсер окончательно «сломался», хотя корень в другом месте. Всегда просматривайте несколько строк вокруг указанной позиции.
Совет для команд:
- Добавьте pre-commit хуки с isort, black и flake8; это снизит количество простых SyntaxError.
Ошибка IndexError — выход за границы последовательности
Описание: IndexError возникает, когда вы пытаетесь обратиться к элементу последовательности (список, кортеж, строка и т.д.) по индексу, который не входит в допустимый диапазон 0..N-1.
Пример:
numbers = [1, 2, 3]
print(numbers[3]) # IndexError: list index out of range
Типичные причины:
- Неправильное ожидание длины данных (off-by-one).
- Изменение коллекции в процессе итерации (удаление/вставка элементов).
- Неправильный парсинг внешнего ввода.
Как предотвращать:
- Используйте безопасный доступ или проверку длины:
if index < len(numbers):
value = numbers[index]
else:
# обработать ситуацию
- Для итерации по элементам предпочитайте for element in sequence, а не индексы, если индексы не нужны.
- При необходимости менять коллекцию во время итерации — итерируйтесь по копии или собирайте элементы для удаления в отдельную коллекцию.
Пример безопасной итерации при удалении:
for item in numbers[:]: # создаём срез-копию
if should_remove(item):
numbers.remove(item)
Критерии приёмки:
- Все участки кода, где есть индексная адресация внешних данных, покрыты тестами на границы (пустой, минимальный, максимальный набор).
Ошибка ValueError — неподходящее значение аргумента
Описание: ValueError возникает, когда функция получает аргумент правильного типа, но недопустимого значения.
Примеры:
int('10') # OK -> 10
int('ten') # ValueError: invalid literal for int()
import math
math.sqrt(-5) # ValueError: math domain error
Частая ситуация — ввод от пользователя: вы не контролируете содержимое, поэтому проверяйте и валидируйте данные.
Обработка через try/except и информативное сообщение:
try:
num = input("Введите число: ")
num_int = int(num)
except ValueError as e:
print(f"Введено недопустимое значение: {e}")
Рекомендации:
- Валидируйте данные до передачи в функцию (принцип “проверяй, не доверяй”).
- Явно документируйте допустимые диапазоны и форматы в docstring.
- Для повторного ввода используйте цикл с ограничением числа попыток.
Мини-методология валидации:
- Проверить тип и формат (регулярные выражения для строк).
- Проверить диапазон/набор допустимых значений.
- Обработать ошибку или вернуть значение по умолчанию.
Критерии приёмки:
- Для парсинга пользовательского ввода есть позитивные и негативные тест-кейсы.
Ошибка AttributeError — у объекта нет требуемого атрибута
Описание: AttributeError возникает, когда вы пытаетесь получить доступ к атрибуту или методу, который отсутствует у объекта. Часто встречается при неправильных предположениях о типе объекта или при работе с None.
Примеры:
text = "hello world"
print(text.push()) # AttributeError: 'str' object has no attribute 'push'
user = None
print(user.name) # AttributeError: 'NoneType' object has no attribute 'name'
Диагностика:
- Проверьте значение переменной и её тип с помощью type() или isinstance().
- Временное добавление print(dir(obj)) помогает увидеть доступные методы и атрибуты.
Практические приёмы:
- Используйте isinstance(obj, ExpectedClass) перед вызовом специфичных методов.
- Для объектов, которые могут быть None, пользуйтесь явной проверкой:
if user is not None:
print(user.name)
else:
# обработка отсутствия пользователя
- Для динамически формируемых объектов документируйте интерфейс (какие методы/свойства должны существовать).
Критерии приёмки:
- Юнит-тесты покрывают сценарии с None и с неподходящими типами.
Общая методика отладки — быстрый чеклист
- Прочитать сообщение об ошибке полностью — строка и позиция часто указывают на источник.
- Смотреть на контекст: несколько строк до и после указанных в сообщении.
- Если SyntaxError — исправьте синтаксис сначала.
- Добавьте временные выводы (print или логирование) для понимания состояния переменных.
- Напишите минимальный воспроизводимый пример (микро-репродьюсер).
- Добавьте тесты, чтобы предотвратить регрессии.
Mermaid-диаграмма принятия решения (отладочный поток):
flowchart TD
A[Программа упала] --> B{Ошибка на этапе парсинга?}
B -- Да --> C[SyntaxError / IndentationError]
B -- Нет --> D{Ошибка времени выполнения}
D --> E{AttributeError?}
D --> F{IndexError?}
D --> G{ValueError?}
E --> H[Проверить тип / None]
F --> I[Проверить границы и модификации при итерации]
G --> J[Валидировать входные данные]
H --> K[Добавить isinstance / dir'']
I --> K
J --> K
K --> L[Добавить тесты и CI]
Ролевые чек-листы
Для разработчика:
- Настроить автоформатирование (black) и линтер.
- Писать понятные docstring с допустимыми типами и диапазонами.
- Покрывать граничные случаи тестами.
Для ревьюера:
- Проверять отступы и наличие табов в изменениях.
- Просматривать обработку ошибок и валидацию входных данных.
- Просить минимальный репродьюсер во всех сложных баг-репортах.
Для QA/тестировщика:
- Подготовить тест-кейсы для пустых, минимальных и максимальных значений.
- Тестировать поведение при некорректном вводе (строки вместо чисел, None и т.д.).
Набор тест-кейсов (пример)
IndexError:
- Пустой список, доступ к [0] — ожидание IndexError или предварительная проверка.
- Доступ к последнему элементу через -1 — должно возвращаться последнее значение.
ValueError:
- int(‘123’) -> OK
- int(‘abc’) -> ожидается исключение ValueError и корректная обработка.
AttributeError:
- Вызов .append() на списке -> OK
- Вызов .append() на строке -> AttributeError; тест должен зафиксировать ошибку или предусмотреть проверку типа.
Короткая шпаргалка команд и инструментов
- black — автоформатирование кода.
- flake8 — статический анализ и ошибки стиля.
- pytest — юнит-тесты и тестовые сценарии.
- pdb / ipdb — интерактивный дебаггер для пошаговой отладки.
Пример запуска pdb:
python -m pdb path/to/script.py
Частые ошибки, когда стандартные советы не помогают
- Ошибка возникает только в CI, но не локально: вероятно, другое окружение (версия Python, локаль, зависимости). Проверьте версии и виртуальное окружение.
- Появляются странные IndentationError в файлах, которые выглядят нормально: проверьте невидимые символы (UTF-8 BOM, смешение табов/пробелов) и настройки git autocrlf.
- ValueError при математических операциях в библиотеке: убедитесь, что вы не передаёте NaN или бесконечность.
Глоссарий в одну строку
- Исключение: сигнал о проблеме во время выполнения или парсинга.
- Парсинг: преобразование текста кода в структуру, понятную интерпретатору.
- Линтер: инструмент статического анализа кода.
Итоги
- Большинство ошибок в Python легко диагностируются по сообщению интерпретатора — начинайте с чтения строки и позиции.
- Настройка инструментов (black, flake8, pytest) значительно сокращает число типичных ошибок.
- Всегда валидируйте внешние данные и покрывайте граничные случаи тестами.
Ключевые шаги на практике:
- Прочитать сообщение об ошибке.
- Сфокусироваться на контексте (несколько строк вокруг).
- Написать минимальный репродьюсер и тест.
Спасибо за чтение — применяйте эти приёмы ежедневно, и типичные ошибки будут быстрее находиться и исправляться.
Похожие материалы

Разные обои для каждого рабочего стола Android

Мониторинг Apache Tomcat: счётчики и правила

Защита от clickjacking: руководство

Разные обои для каждого экрана Android

Удаление данных с сайтов брокеров
