EOFError: EOF when reading a line — что значит и как исправить

опубликовано
читать
≈ 4 мин
автор
среда и версия
CPython 3.11 в терминале Debian 12 и Docker 29; исполняемые блоки — Python 3.14 в Pyodide 314.0.3 прямо на странице
содержание решать задачи Python для начинающих

EOFError: EOF when reading a line переводится как «конец файла при чтении строки». input() ждал строку из стандартного ввода, а ввод оказался закрыт или уже кончился. С самим кодом всё в порядке: input() написан правильно, но программе нечего прочитать. Поэтому чинить нужно то, откуда программа берёт ввод, — или научить её спокойно заканчивать чтение.

Python / 01

Откуда input() берёт строку

Откуда input() берёт строкуПрограмма profile.py дважды вызывает input: сначала имя, потом город. Три способа запуска. 01 — в терминале человек вводит обе строки: оба input получают ответ. 02 — echo "Аня" | python3 profile.py: в конвейере одна строка, имя прочитано, а второй input получает конец ввода — EOFError. 03 — ввода нет совсем: перенаправление из /dev/null, Docker без -i, блок на странице без поля ввода — первый же input даёт EOFError.откуда вводprofile.py: input("Имя: "), потом input("Город: ")01 терминалчеловек вводит обе строки02 конвейерecho "Аня" |03 ввода нет/dev/null, Docker без -iАня из города Казаньимя: Анягород: EOFErrorимя: EOFError
Каждый input() забирает одну строку ввода. Кончились строки — следующий input() получает конец ввода и бросает EOFError.

Как выглядит ошибка

Программа спрашивает имя и здоровается:

name = input("Как тебя зовут? ")
print(f"Привет, {name}!")

Если ввода нет — например, его перенаправили из пустого /dev/null, — вопрос печатается, а ответа нет:

python3 greet.py < /dev/null
Как тебя зовут? Traceback (most recent call last):
  File "/home/dev/greet.py", line 1, in <module>
    name = input("Как тебя зовут? ")
           ^^^^^^^^^^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line

Трассировка прилипла к вопросу, потому что input() печатает подсказку без перевода строки, а дождаться ответа не смог.

Попробуй прямо здесь

Примеры на этой странице запускаются кнопкой, но поля для ввода у них нет. Поэтому input() здесь сразу получает конец ввода — та же ситуация, что в онлайн-редакторах без окна ввода:

name = input("Как тебя зовут? ")
print(f"Привет, {name}!")
Как тебя зовут? 
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    name = input("Как тебя зовут? ")
           ~~~~~^^^^^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line

В песочнице Python под кодом есть поле «ввод (stdin)»: каждая его строка уходит в очередной input(). Там тот же код поздоровается.

Ввод кончился раньше, чем ждала программа

Каждый input() забирает ровно одну строку. Если строк меньше, чем вызовов, последние из них получают конец ввода. Программа profile.py спрашивает имя и город, а в конвейере только имя:

echo "Аня" | python3 profile.py
Имя: Город: Traceback (most recent call last):
  File "/home/dev/profile.py", line 2, in <module>
    city = input("Город: ")
           ^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line

Имя прочиталось, город — нет. С онлайн-проверкой задач то же самое: тест подаёт ровно столько строк, сколько написано в условии. Если программа читает лишнюю строку, на ней будет EOFError. Сверь число вызовов input() с форматом ввода в условии.

Как читать ввод до конца

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

total = 0
while True:
    line = input()
    total += int(line)
print(total)
printf "3\n5\n10\n" | python3 sum.py
Traceback (most recent call last):
  File "/home/dev/sum.py", line 3, in <module>
    line = input()
           ^^^^^^^
EOFError: EOF when reading a line

Правильно — перебирать sys.stdin: цикл сам закончится вместе с вводом. Здесь ввод подменён строкой через io.StringIO, чтобы пример работал на странице, а в настоящей программе первые две строки после импортов не нужны:

import io
import sys

sys.stdin = io.StringIO("3\n5\n10\n")

total = 0
for line in sys.stdin:
    total += int(line)
print(total)
18

Второй способ — поймать конец ввода как сигнал «всё прочитано»:

total = 0
while True:
    try:
        line = input()
    except EOFError:
        break
    total += int(line)
print(total)
printf "3\n5\n10\n" | python3 sum_eof.py
18

Как устроены try и except, рассказано в статье про try/except.

Docker, cron и другие запуски без клавиатуры

Программа в контейнере, запущенном без ключа -i, не получает стандартный ввод вовсе:

docker run --rm app python3 -c 'name = input("Имя: ")'
Имя: Traceback (most recent call last):
  File "<string>", line 1, in <module>
EOFError: EOF when reading a line

Ключ -i подключает ввод. Через него можно передать данные конвейером, а для диалога с человеком добавляют ещё -t: docker run -it app python3 main.py.

echo "Аня" | docker run --rm -i app python3 -c 'name = input("Имя: "); print("Привет,", name)'
Имя: Привет, Аня

Задачи cron, службы systemd и шаги CI тоже запускаются без клавиатуры. Программе, которая работает там, данные передают аргументами, переменными окружения или файлом, а не через input(). Как задать переменные окружения, разобрано в отдельной статье.

Редакторы и Ctrl+D

В редакторах ошибка появляется, когда программа запущена в окне вывода, куда нельзя печатать. Открой встроенный терминал (в VS Code это Terminal → New Terminal) и запусти программу там: python3 main.py.

В самом терминале конец ввода можно отправить вручную: в Linux и macOS это Ctrl+D, в Windows — Ctrl+Z и Enter. Python тогда сообщает об ошибке короче, без текста после двоеточия:

Как тебя зовут? Traceback (most recent call last):
  File "/home/dev/greet.py", line 1, in <module>
    name = input("Как тебя зовут? ")
           ^^^^^^^^^^^^^^^^^^^^^^^^^
EOFError

Ctrl+C — это другое: он прерывает программу и даёт KeyboardInterrupt.

Частые вопросы

Как перевести EOF when reading a line

«Конец файла при чтении строки». EOF, end of file, — сигнал, что данных во вводе больше нет. Для input() стандартный ввод — такой же поток, как файл.

Почему у меня работает, а в онлайн-проверке нет

Дома ты вводишь строки сам и можешь ввести лишнюю, а проверка подаёт ровно то, что в тесте. Если программа вызывает input() больше раз, чем строк в тесте, последний вызов получит конец ввода. Сверь число вызовов с форматом ввода.

Нужно ли оборачивать каждый input() в try/except

Нет. except EOFError нужен там, где конец ввода — нормальное окончание данных, как при чтении до конца. В остальных случаях ошибка честно сообщает, что программу запустили без ввода, и это стоит исправить, а не прятать.

Источники

Выжимки статей в Telegram: одна ловушка, код с выводом и ссылка на полный разбор. t.me/koddo_ru