Гид по технологиям

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

7 min read Python Обновлено 16 Sep 2025
5 распространённых ошибок в Python и как их исправить
5 распространённых ошибок в Python и как их исправить

Логотип Python на размытом фоне кода, желтая подпись '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 не принимает коммиты с табуляцией (если политика проекта — пробелы).

Пример ошибки IndentationError: стрелки указывают на несоответствующий отступ.

Ошибка 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.

Иллюстрация 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)

Критерии приёмки:

  • Все участки кода, где есть индексная адресация внешних данных, покрыты тестами на границы (пустой, минимальный, максимальный набор).

Иллюстрация IndexError: консоль показывает сообщение об ошибке при обращении к несуществующему индексу.

Ошибка 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.
  • Для повторного ввода используйте цикл с ограничением числа попыток.

Мини-методология валидации:

  1. Проверить тип и формат (регулярные выражения для строк).
  2. Проверить диапазон/набор допустимых значений.
  3. Обработать ошибку или вернуть значение по умолчанию.

Критерии приёмки:

  • Для парсинга пользовательского ввода есть позитивные и негативные тест-кейсы.

Иллюстрация ValueError: сообщение о неверном значении при попытке преобразовать строку в число.

Ошибка 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 и с неподходящими типами.

Иллюстрация AttributeError: окно ошибки показывает, что объект не имеет запрошенного атрибута.

Общая методика отладки — быстрый чеклист

  1. Прочитать сообщение об ошибке полностью — строка и позиция часто указывают на источник.
  2. Смотреть на контекст: несколько строк до и после указанных в сообщении.
  3. Если SyntaxError — исправьте синтаксис сначала.
  4. Добавьте временные выводы (print или логирование) для понимания состояния переменных.
  5. Напишите минимальный воспроизводимый пример (микро-репродьюсер).
  6. Добавьте тесты, чтобы предотвратить регрессии.

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) значительно сокращает число типичных ошибок.
  • Всегда валидируйте внешние данные и покрывайте граничные случаи тестами.

Ключевые шаги на практике:

  1. Прочитать сообщение об ошибке.
  2. Сфокусироваться на контексте (несколько строк вокруг).
  3. Написать минимальный репродьюсер и тест.

Спасибо за чтение — применяйте эти приёмы ежедневно, и типичные ошибки будут быстрее находиться и исправляться.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

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

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

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

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

Защита от clickjacking: руководство
Кибербезопасность

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

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

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

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

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

Разные обои для каждой домашней страницы Android
Android.

Разные обои для каждой домашней страницы Android