2016-04-09 4 views
1

Я хочу перенаправить файл в качестве стандартного ввода в свой сценарий Python, но получаю некоторые ошибки, как только он пытается собрать вход. Простой MWE будет:Невозможно перенаправить стандартный ввод на скрипт Python

Сценарий, как это:

T = int(input()) 

for i in range(T): 
    stack = input() 

И команда, как это в ЦМД окна:

script.py > someOut.out < someIn.in 

И мой входной файл будет иметь содержание, как:

[Int] 
[String] 
[String] 
... 

Он получает количество тестов правильно, но как только он видит строку, он всегда выдает некоторые исключения Тион. Например, для файла типа:

1 
kdjddhs 

Я получаю NameError: name 'kdjddhs' is not defined. В то же время, файл:

1 
+-= 

бросает:

File "<string>", line 1 
    +-= 
    ^
SyntaxError: unexpected EOF while parsing 

Почему это так? Когда я запускаю скрипт через интерпретатор, все работает нормально. Как я могу обрабатывать ввод таким образом, чтобы я мог перенаправить стандартный ввод через командную строку, а не обрабатывать фактический текстовый файл через сам сценарий?

+0

Я не очень понимаю, но вы пробовали использовать строку в качестве входного типа данных, а затем проверить, если это номер, и если это вы можете преобразовать его в int и сказать: в диапазоне (T): – frankenapps

+0

Код работает отлично здесь, в Linux и Python3. Возможно, это проблема Windows. – mkiever

ответ

1

Вы используете неправильный интерпретатор на SheBang. Я тестировал следующий код как с питона версии 2 и 3 (Обратите внимание, что притон определяет версию):

#!/usr/bin/env python3 

import sys 
print(sys.version) 

T = int(input()) 

for i in range(T): 
    stack = input() 
    print(stack) 

Теперь на питоне 2 ничего не работает.Оба использования интерпретатора python2 ./test.py < data.in и вызова файла непосредственно приводит к ошибке:

данных:

1 
stack-123 

Выход:

2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] 
Traceback (most recent call last): 
    File "./test.py", line 9, in <module> 
    stack = input() 
    File "<string>", line 1, in <module> 
NameError: name 'stack' is not defined 

Использование python3 как python3 ./test.py < data.in и ./test.py < ./data.in работу, как ожидалось. Изменение хижину к #!/usr/bin/env python который не определяет интерпретатор питона системы по умолчанию используется в вашем случае является Python 2.x и приводит к ошибке

Я не могу сказать вам, почему питон 2 не работает - кажется, он пытается оценить stack-123 как переменную, называемую «стек», и отбрасывает часть -123 ... Я сделаю некоторое исследование по этому вопросу и уточню ответ, если я это выясню, но использование правильной shebang решит вашу проблему.

Обновление: Как говорит @GurgenHovhannisyan (+1 от меня), который я полностью забыл, в python2 вместо этого вы должны использовать raw_input(), чтобы достичь такого же поведения. Если вы хотите, чтобы работать в обеих версиях, определить и использовать следующую функцию:

def myInput(): 
    try: 
     # this will fail in python 3 
     return raw_input() 
    except: 
     return input() 

Надеется, что это помогает

+0

Ваше замечание о shebang привело меня к ответу - вместо python 3 использовался интерпретатор python 2, поскольку я их устанавливал рядом друг с другом :) Решила, спасибо. – Straightfw

1

Прежде всего, это не имеет значения через переводчика или нет. Версия python здесь имеет смысл. Если вы работаете с Python версии 2., вышеупомянутый вход будет работать. Если вы находитесь на Python 3., не будет. функция Поскольку вход() работает по-разному в зависимости от версии Python

Python версии 2:

  • input() - читать ввод и оценивает
  • raw_input() - считывают данные в качестве исходного строки

Python версия 3:

  • input() - работает как raw_input() в 2
  • raw_input() - нет эта функция

Так просто изменить ваш вход raw_input, если вы находитесь в Python 2.

+0

Ваши определения функций верны, но вы включили его в свой первый абзац. Он будет * не * работать в Python 2, но он * будет * работать в Python 3. – zondo

+0

Вещь - это я. Я использую Python 3, я даже пытался добавить явный python3 shebang, но та же проблема сохраняется. – Straightfw

1

Это должно работать так же для 2.x Python и Python 3.x:

from __future__ import print_function 
import sys 


stdin_reader = None 

# python version check determines our choice of input function 
try: 
    if (sys.version_info > (3, 0)): 
     stdin_reader = input 
    else: 
     stdin_reader = raw_input 
# Yes yes, I know - don't catch all exceptions 
# but here we want to quit if anything fails regardless of the error. 
except: 
    print("Failed to determine Python version") 

def echo_stdin(): 
    """ Reads stdin and prints it back in upper case """ 
    r = stdin_reader() 
    print(r.upper()) 

echo_stdin() 

Выход:

$ python3 echo_stdin.py < data_stdin 
SOME INPUT LALALA 
$ python echo_stdin.py < data_stdin 
SOME INPUT LALALA