Ошибка EOF Python в raw_input()

Я пытаюсь получить ввод от пользователя в командной строке. Программа считывает данные из текстового файла в виде "cat text.txt | ./thescript.py"

На момент рассматриваемого скрипта все данные уже прочитаны, обработаны и помещены в список списков.

Теперь я просматриваю этот список списков в поисках сомнительных элементов. Код в основном выглядит так:

for invoice in parsedlist:
      if invoice[-1] == 3:
          sys.stderr.write("triple duplicate at " + invoice[2]+' : ' + invoice[3]+"\n")
          sys.stderr.write("continue Y or N \n")
          answer = raw_input("Type your answer here")
          if answer == 'N':
              sys.exit(1)
          else: 
              pass`

Этот код приводит к ошибке EOFError. Из того, что я уже понял, в этом случае stdin является чтением из cat, и, поскольку он уже достиг EOF, почему raw_input получает здесь EOF? (Я думаю) Цель состоит в том, чтобы сценарий печатал предупреждение о стандартной ошибке и позволял мне выбирать, игнорировать ли предупреждение и продолжать или полностью выйти. В конце концов, все выходные данные выводятся на стандартный вывод и не включают ни предупреждений об ошибках, ни ответов. Я видел примеры, в которых используется попытка/исключение, но я не смог понять это в этом контексте. (Например. Почему raw_input не ждет ввода?)

Я думаю, что, возможно, я просто неправильно решаю эту проблему и, таким образом, создаю проблему, которую лучше обойти, чем перепрыгнуть. Любая помощь приветствуется, как всегда.


person Wyatt    schedule 26.07.2011    source источник
comment
Извините за отступы. Они были в оригинале.   -  person Wyatt    schedule 26.07.2011
comment
cat text.txt | ./thescript.py обычно пишется как ./thescript.py < text.txt.   -  person Karl Knechtel    schedule 26.07.2011
comment
если только он не упрощает эту левую часть, чтобы она не отвлекала нас от проблемы... ;)   -  person John Gaines Jr.    schedule 26.07.2011


Ответы (3)


Да, проблема в том, что ваш raw_input() читает со стандартного ввода, который является выходом cat, который находится в EOF.

Мое предложение состояло бы в том, чтобы устранить cat. Это не обязательно; Python вполне способен читать файлы самостоятельно. Передайте имя файла в командной строке, откройте его и прочитайте сами.

import sys

for line in open(sys.argv[1]):
    # process line

Если вам нужно обрабатывать несколько файлов, проверьте модуль fileinput; он легко справляется с чтением нескольких файлов, как если бы они были одним целым, что и делает для вас cat.

person kindall    schedule 26.07.2011
comment
Я думал, что это прогулка, а не перепрыгнуть! Спасибо. Кажется очевидным теперь, когда ты это сказал. Шелл — это привычка, от которой трудно избавиться. :) - person Wyatt; 26.07.2011
comment
cat может быть плохой привычкой даже в шелле. Если вы на самом деле не объединяете файлы, обычно вы можете сохранить процесс, перенаправив стандартный ввод в файл. например cat foo | grep bar такой же, как grep bar <foo, за исключением того, что на один процесс меньше. - person kindall; 26.07.2011

Это работает под Windows (я проверил это, запустив python cons.py < cons.py и смог увидеть подсказку и не получить сообщение об ошибке EOF):

import sys

for line in sys.stdin:
    print line

sys.stdin = open('CON', 'r')
q = raw_input('---->')

В Unix вам, вероятно, просто нужно заменить «CON» на что-то в каталоге /dev.

person John Gaines Jr.    schedule 26.07.2011

Цель состоит в том, чтобы сценарий печатал предупреждение о стандартной ошибке и позволял мне выбирать, игнорировать ли предупреждение и продолжать или полностью выйти.

Вы хотите, чтобы выбор исходил из интерактивной подсказки, а данные поступают из файла? Что ж, теперь вы делаете что-то отличное от исходной программы: вы читаете эти две вещи из разных мест, где раньше они были взяты из одного и того же места. Поэтому вам нужно обновить свой дизайн, чтобы учесть это.

Почему raw_input не ждет ввода

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

person Karl Knechtel    schedule 26.07.2011