IndentationError: expected an indented block — как исправить в Python
Indentation (отступы) — критичная часть синтаксиса Python. Явные блоки кода создаются отступами, и интерпретатор ожидает тело после заголовков блоков. Если тело отсутствует или отступ задан неверно, вы увидите ошибку IndentationError, часто с уточнением, после какого выражения ожидался отступ.
Почему появляется IndentationError: expected an indented block
Python использует отступы вместо фигурных скобок для выделения блоков. Каждый двоеточие (:) в конце строки обычно открывает блок:
- if, elif, else
- for, while
- def, class
- try/except/finally, with
Если после строки с двоеточием нет строки с увеличенным отступом (тела блока), интерпретатор выдаёт IndentationError с текстом “expected an indented block”. Новички и разработчики, переходящие с языков, где блоки обозначаются фигурными скобками, сталкиваются с этой ошибкой чаще всего.
Важно: путаница между табуляцией и пробелами — частая причина ошибок. Никогда не смешивайте их в одном файле.
Примеры: ошибка и исправление
Ниже пример из простого сценария, где тело if не было отступлено.
Неправильно:
fname = "Gaurav"
lname = "Siyal"
if fname == "Gaurav" and lname == "Siyal":
print("You're Gaurav")
else:
print("You're somebody else")При запуске такого файла Python сообщит примерно следующее (путь и номера строк зависят от файла):
File "tmp.py", line 5
print("You're Gaurav")
^
IndentationError: expected an indented block after 'if' statement on line 4Правильный вариант (используем 4 пробела по PEP 8):
fname = "Gaurav"
lname = "Siyal"
if fname == "Gaurav" and lname == "Siyal":
print("You're Gaurav")
else:
print("You're somebody else")Обратите внимание: корректный отступ — это не только эстетика. Это синтаксис.
Ошибка “unexpected indent”
Сообщение “IndentationError: unexpected indent” означает, что вы случайно добавили отступ в месте, где интерпретатор его не ожидает. Пример:
num = 5
num += 2Решение — убрать лишний отступ:
num = 5
num += 2Проверка настроек редактора и автоматизация
Большинство современных редакторов и IDE автоматически управляют отступами. Проверьте настройки, чтобы обеспечить единообразие:
- Настройте использование пробелов вместо табов или наоборот, но не смешивайте.
- Установите ширину табуляции (обычно 4 пробела в Python).
- Включите видимые символы пробелов/табов, чтобы заметить смешение.
В Spyder можно найти опции в меню Tools > Preferences > Source code.
Если вы используете Vim, конфигурация может выглядеть так:
set autoindent
set expandtab
set tabstop=4
set softtabstop=4
set shiftwidth=4Эти опции обеспечат автоматический переход на 4 пробела при нажатии Tab.
Советы по автоматизации качества кода:
- Форматтеры: Black, autopep8 — автоматически приводят код к единому стилю.
- Линтеры: Flake8, pylint — ищут смешение табов/пробелов и другие ошибки стиля.
- Pre-commit hook: запускайте форматтер и линтер перед коммитом.
Частые случаи неправильных отступов и решения
If-операторы
Ошибка: ожидается тело после if. Решение: поместите тело под строкой if и сделайте отступ на один уровень.
if my_name == "Gaurav":
print("My name is Gaurav")Функции
Ошибка: ожидается тело после определения функции. Решение: добавьте отступ сразу после def.
def magic_number():
result = 42
return result
print(magic_number())Циклы for/while
Ошибка: отсутствует тело цикла. Решение: отступите строки тела цикла.
for i in range(10):
print(i)Докстринги без отступа
Докстринг в теле функции должен иметь правильный отступ, иначе возникнет IndentationError:
def do_something():
"""Эта функция что-то делает"""
return TrueМетодика отладки: быстрый SOP
- Прочитайте сообщение об ошибке и найдите номер строки.
- Перейдите к указанной строке и проверьте предыдущую строку — обычно там стоит двоеточие (:).
- Проверьте, есть ли после двоеточия строка с увеличенным отступом.
- Убедитесь, что файл использует либо пробелы, либо табы. В редакторе включите отображение невидимых символов.
- Запустите линтер (flake8/pylint). Он подскажет смешение табов и пробелов и другие проблемы.
- Если не помогло — минимизируйте файл до репродуцируемого примера и повторите проверку.
Чек-лист по ролям
Разработчик:
- Использовать форматтер (black/autopep8) перед коммитом.
- Не смешивать табы и пробелы.
- Проверять изменения в diff на предмет отступов.
Ревьюер кода:
- Просмотреть изменения на предмет неконсистентных отступов.
- Просить автора запустить форматтер, если стиль нарушен.
CI/DevOps:
- Добавить проверку стиля в пайплайн (flake8 + black).
- Отклонять PR с ошибками форматирования.
Шпаргалка: отступы и шаблоны (cheat sheet)
- Блоки: 4 пробела (PEP 8)
Примеры:
If/else:
if condition:
do_something()
else:
do_something_else()Функция:
def func(arg):
# тело функции
return arg * 2Класс:
class MyClass:
def method(self):
passМногострочные выражения (с продолжением):
total = (
first_value
+ second_value
+ third_value
)Когда исправление может не помочь (контрпример)
- Файл содержит невидимые символы (например, неразрывные пробелы) — визуально строки выглядят правильно, но Python всё равно жалуется. Решение: заменить пробелы в файле программно (например, через sed или утилиту в редакторе).
- Автоматический форматтер не применим из-за специфических соглашений проекта. В этом случае согласуйте стиль в команде и добавьте исключения в конфиг форматтера.
Тесты и критерии приёмки
Критерии приёмки:
- Скрипт запускается без IndentationError.
- flake8 не сообщает об ошибках смешения табов/пробелов.
- Автоформаттер не вносит неожиданных изменений в логику (только стиль).
Минимальные тесты:
- Запускать модуль через python -m pytest на наборе простых тестов. Если во время импорта возникнет IndentationError, тесты не запустятся.
- Статическая проверка: flake8 –select=E1,E9 (где E1/E9 включают ошибки форматирования и синтаксиса в зависимости от конфигурации).
Альтернативные подходы и инструменты
- Black: жёсткий форматтер, который автоматически выравнивает отступы под единую схему.
- autopep8: автоисправление под PEP 8.
- Flake8 / pylint: статический анализ, указывающий на смешение табов/пробелов.
- IDE/Editor plugins: включение «show whitespace», «convert tabs to spaces» и автосохранение с применением форматтера.
Краткая методика восстановления файла с проблемными отступами
- Сделайте резервную копию файла.
- Откройте файл в редакторе с видимыми пробелами/табуляцией.
- Выполните замену всех табов на 4 пробела (или наоборот, согласно принятому в проекте стилю).
- Запустите линтер и форматтер.
- Протестируйте запуск скрипта.
Ментальные модели и эвристики
- Двоеточие (:) означает: “я ожидаю тело блока”.
- Один уровень отступа = одна логическая вложенность.
- Если не уверены — минимизируйте код до пары строк, чтобы воспроизвести проблему.
1‑строчная глоссарий
- Отступ (indent) — пробелы или табы в начале строки, обозначающие вложенность блока.
- TabError — специальный тип ошибки при смешении табов и пробелов в Python.
- PEP 8 — рекомендация по стилю кода для Python; советует 4 пробела для отступов.
- Линтер — инструмент статической проверки кода (например, flake8).
- Форматтер — инструмент автоправки стиля (например, black).
Резюме
- IndentationError: expected an indented block означает отсутствие или неправильный отступ после конструкции с двоеточием.
- Чаще всего помогает единообразный стиль отступов: используйте 4 пробела по PEP 8 и не смешивайте табы и пробелы.
- Настройте редактор, добавьте форматтер и линтер в процесс разработки и CI.
Важно: согласуйте стиль отступов в команде и автоматизируйте проверку — тогда большая часть подобных ошибок исчезнет ещё на этапе коммита.