Как вы читаете со стандартного ввода?

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

Ответы на вопрос(19)

n = int(raw_input())
for i in xrange(n):
    name, number = raw_input().split()

Вот'с изИзучение Python:

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

В Unix вы можете проверить это, выполнив что-то вроде:

% cat countlines.py | python countlines.py 
Counted 3 lines.

В Windows или DOS выбуду делать:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.
 istepaniuk17 нояб. 2015 г., 12:14
Использованиеcat здесь избыточно. Правильный вызов для систем Unix ".python countlines.py < countlines.py
 Aaron Hall01 авг. 2016 г., 16:56
Изучение Питона " неверно указывать пользователям использоватьreadlines(), Файловые объекты предназначены для итерации без материализации всех данных в памяти.
 jfs16 нояб. 2012 г., 05:32
Вот'Это более эффективный для памяти (и, возможно, более быстрый) способ подсчета строк в Python:.print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 < 15), '')))

Это отобразит стандартный ввод в стандартный вывод:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

Ответ, предложенный другими:

for line in sys.stdin:
  print line

очень прост и питоничен, но следует отметить, что сценарий будет ждать до EOF, прежде чем начать итерацию по строкам ввода.

Это означает, чтоtail -f error_log | myscript.py не будет обрабатывать строки, как ожидалось.

Правильный сценарий для такого варианта использования будет:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

ОБНОВИТЬ

Из комментариев выяснилось, что только в python 2 может быть задействована буферизация, так что вы в конечном итоге ожидаете заполнения буфера или EOF перед вызовом печати.

 jfs23 янв. 2016 г., 08:46
@MattFreeman: это не имеет отношения кСтроковая или блочная буферизация в зависимости от того, является ли stdout tty в этом случае. Ошибка опережающего чтения в Python 2 задерживает ввод, даже еслиtail должны были вовремя очистить свою продукцию.for line in sys.stdin отлично работает на Python 3.
 Sean15 окт. 2013 г., 13:34
мой питон 2.7.5 "для строки в sys.stdin ", блоки до EOF или некоторое разумное количество данных буферизовано. Штраф за потоковую обработку. Не подходит для построчной обработки или ввода данных пользователем.
 musiphil27 февр. 2019 г., 19:35
for line in sys.stdin: во всяком случае, не предназначен для действительно интерактивного ввода (например, получения ввода от терминала после подсказок). В большинстве случаев вас не должно волновать, буферизован ли ввод или нет.
 Mâtt Frëëman12 мар. 2015 г., 09:16
Я подозреваю, что это связано с обнаружением tty в libc, поэтому, когда вы обнаруживаете, что он обнаруживает в интерактивной оболочке, он не обнаруживает tty, небуферизация от ожидаемого-dev - это полезная утилита, которая, как я считаю, вставляет шим через ld_preload, поэтому is_atty возвращает true (я подозреваю, чтоs как это передать)
 ctrl-alt-delor07 сент. 2012 г., 11:41
Я получаю ожидание окончания файла или буферизации при получении ввода из потока при использовании Python 2.6.6, но с 3.1.3 я нет. Заметкаprint line не проснулся в 3.1.3, ноprint(line) делает.
 mb.11 июл. 2012 г., 04:06
for line in sys.stdin: шаблонне ждать EOF. Но если вы тестируете очень маленькие файлы, ответы могут быть помещены в буфер. Протестируйте с большим количеством данных, чтобы увидеть, что он читает промежуточные результаты.
 jfs23 янв. 2016 г., 08:38
@Sean:неправильно.for line in sys.stdin: не "блок до EOF ", Eстьошибка чтения в Python 2 это задерживает строки, пока соответствующий буфер не будет заполнен. Это проблема буферизации, которая не связана с EOF. Чтобы обойти это, используйтеfor line in iter(sys.stdin.readline, ''): (использованиеio.open() для обычных файлов). Ты неэто не нужно в Python 3.

Читать изsys.stdin, ночитать двоичные данные в WindowsВы должны быть очень осторожны, потому чтоsys.stdin там открыт в текстовом режиме и он будет поврежден\r\n заменив их на.\n

Решение состоит в том, чтобы установить режим в двоичный режим, если обнаружен Windows + Python 2, и использовать Python 3.sys.stdin.buffer

import sys

PY3K = sys.version_info >= (3, 0)

if PY3K:
    source = sys.stdin.buffer
else:
    # Python 2 on Windows opens sys.stdin in text mode, and
    # binary data that read from it becomes corrupted on \r\n
    if sys.platform == "win32":
        # set sys.stdin to binary mode
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    source = sys.stdin

b = source.read()

В соответствии с этим:

for line in sys.stdin:

Я только что попробовал это на Python 2.7 (после кого-то еще "с) очень большой файл, и я неЯ не рекомендую это именно по причинам, упомянутым выше (долгое время ничего не происходит).

Я получил немного более питонное решение (и оно работает с большими файлами):

with open(sys.argv[1], 'r') as f:
    for line in f:

Затем я могу запустить скрипт локально как:

python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
 szeitlin17 сент. 2016 г., 11:37
@DeFazer отредактирован, чтобы показать, как его использовать. Аргументы - это строки, да, но, как я уже упоминал в документации по Python в предыдущем комментарии,sys.stdin это файловый объект
 DeFazer17 сент. 2016 г., 04:12
Как ты мог пройтиsys.stdin в качестве аргумента командной строки для сценария? Аргументы - это строки, а потоки - это файловые объекты, они не одинаковы.
 Aaron Hall01 авг. 2016 г., 15:27
Открытие файла не читает со стандартного ввода, как вопрос. -1
 szeitlin02 авг. 2016 г., 00:56
В этом случае я прохожу вsys.stdin в качестве аргумента командной строки для сценария.

Вы могли бы использоватьfileinput модуль:

import fileinput

for line in fileinput.input():
    pass

fileinput будет проходить по всем строкам ввода, указанным в качестве имен файлов, указанных в аргументах командной строки, или стандартного ввода, если аргументы не предоставлены.

Замечания:line будет содержать завершающий перевод строки; чтобы удалить это использоватьline.rstrip()

 Borislav Stoilov13 апр. 2019 г., 16:21
Вопрос о чтении из процесса std в потоке. Как Cin в C

Следующий фрагмент кода поможет вам (он будет читать все блокирование stdin кEOFв одну строку):

import sys
input_str = sys.stdin.read()
print input_str.split()

У меня были некоторые проблемы при получении этого для работы через сокеты, переданные по каналу. Когда сокет закрылся, он начал возвращать пустую строку в активном цикле. Так что это мое решение (которое я тестировал только в Linux, но надеюсь, что оно работает во всех других системах)

import sys, os
sep=os.linesep

while sep == os.linesep:
    data = sys.stdin.readline()               
    sep = data[-len(os.linesep):]
    print '> "%s"' % data.strip()

Так что, если вы начнете прослушивать сокет, он будет работать правильно (например, в bash):

while :; do nc -l 12345 | python test.py ; done

И вы можете позвонить с помощью telnet или просто указать браузер на localhost: 12345

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

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

и использовать его как либо

$ python do-my-stuff.py infile.txt

или же

$ cat infile.txt | python do-my-stuff.py

или даже

$ python do-my-stuff.py < infile.txt

Это сделало бы ваш скрипт Python вести себя как многие программы GNU / Unix, такие как,catgrep а также .sed

argparse это простое решение

Пример совместим с обеими версиями Python 2 и 3:

#!/usr/bin/python

import argparse
import sys

parser = argparse.ArgumentParser()

parser.add_argument('infile',
                    default=sys.stdin,
                    type=argparse.FileType('r'),
                    nargs='?')

args = parser.parse_args()

data = args.infile.read()

Вы можете запустить этот скрипт разными способами:

1. Использованиеstdin

echo 'foo bar' | ./above-script.py

 или короче, заменивecho отВот строка:

./above-script.py < 'foo bar'
 Locane09 апр. 2019 г., 00:03
Это было здорово.
 Ken Colton23 дек. 2018 г., 22:52
in ISN»просто плохое имя для переменной, это недопустимо.args.in.read() вызовет ошибку InvalidSyntax из-заin зарезервированное ключевое слово Можно просто переименовать вinfile как это делают документы на python argparse:docs.python.org/3/library/...
 tommy.carstensen04 дек. 2018 г., 14:59
Вот ответ, что делать, если входной файл сжат:stackoverflow.com/a/33621549/778533 Можно также сделатьadd_argument('--in' а затем труба к сценарию и добавить--in - в командной строке. Постскриптумin не очень хорошее имя для переменной / атрибута.
 olibre27 дек. 2018 г., 22:20
Спасибо @ tommy.carstensen за ваш отзыв, я только что улучшил ответ. Веселого Рождества и счастливого Нового года ;-)

Там'Есть несколько способов сделать это.

sys.stdin это файловый объект, на котором вы можете вызывать функцииread или жеreadlines если вы хотите прочитать все или вы хотите прочитать все и разделить его на новую строку автоматически. (Вам нужноimport sys чтобы это работало.)

Если хотитенезамедлительный пользователь для ввода, вы можете использоватьraw_input в Python 2.X, и простоinput в Python 3.

Если вы на самом деле просто хотите прочитать параметры командной строки, вы можете получить к ним доступ черезsys.argv список.

Вы, вероятно, найдетеэта статья Wikibook о вводе / выводе в Python быть полезным справочником.

Как вы читаете со стандартного ввода в Python?

Я пытаюсь выполнить некоторые задачи кода, но все они требуют ввода от stdin. Как мне получить это в Python?

Ты можешь использовать:

sys.stdin - Файловый объект - вызовsys.stdin.read() читать всеinput(prompt) - передать ему необязательный запрос на вывод, он читает от стандартного ввода до первой новой строки, которую он удаляет. Вы'Я должен сделать это несколько раз, чтобы получить больше строк, в конце ввода он вызывает EOFError. (Вероятно, не подходит для игры в гольф.) В Python 2 это так.rawinput(prompt)open(0).read() - в Python 3open принимаетфайловые дескрипторы (целые числа, представляющие ресурсы ввода-вывода операционной системы), а 0 - дескрипторstdin, Возвращает подобный файлу объект какsys.stdin - вероятно, ваш лучший выбор для игры в гольф.open('/dev/stdin').read() - похожий наopen(0), работает на Python 2 и 3, но не на Windows (или даже Cygwin).fileinput.input() - возвращает итератор над строками во всех файлах, перечисленных вsys.argv[1:]или стандартный ввод, если не дано. Используйте как.''.join(fileinput.input())

И то и другоеsys а такжеfileinput должны быть импортированы, соответственно, конечно.

Быстрыйsys.stdin примеры совместимые с Python 2 и 3, Windows, Unix

Вам просто нужноread отsys.stdinНапример, если вы передаете данные в stdin:

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo
пример файла

Скажем, у вас есть файл,inputs.txtмы можем принять этот файл и записать его обратно:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
Более длинный ответ

Вот's полная, легко воспроизводимая демонстрация с использованием двух методов, встроенной функции,input (использованиеraw_input в Python 2) иsys.stdin, Данные не изменены, поэтому обработка не является операцией.

Для начала, давайтеs создать файл для входных данных:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

И используя код, который мымы уже видели, мы можем проверить, что мымы создали файл:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

Вот'с помощьюsys.stdin.read из Python 3:

read(size=-1, /) method of _io.TextIOWrapper instance
    Read at most n characters from stream.

    Read from underlying buffer until we have n characters or we hit EOF.
    If n is negative or omitted, read until EOF.
Встроенная функция, (inputraw_input в Python 2)

Встроенная функцияinput читает со стандартного ввода до новой строки, которая удаляется (дополняетprint, который добавляет новую строку по умолчанию.) Это происходит до тех пор, пока не получит EOF (конец файла), после чего он поднимается.EOFError

Таким образом, здеськак вы можете использоватьinput в Python 3 (илиraw_input в Python 2) для чтения из stdin - поэтому мы создаем модуль Python, который мы называем stdindemo.py:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

И разреши's распечатать его обратно, чтобы убедиться, чтокак мы ожидаем:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

Снова,input читает до новой строки и по существу удаляет его из строки.print добавляет новую строку. Поэтому, пока они оба изменяют ввод, их модификации отменяются. (Так что они по сути друг другас дополнением.)

И когдаinput получает символ конца файла, он вызывает EOFError, которую мы игнорируем и затем выходим из программы.

А в Linux / Unix мы можем передать из cat:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

Или мы можем просто перенаправить файл из stdin:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

Мы также можем выполнить модуль как скрипт:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

Вот'S помощь по встроеннымinput из Python 3:

input(prompt=None, /)
    Read a string from standard input.  The trailing newline is stripped.

    The prompt string, if given, is printed to standard output without a
    trailing newline before reading input.

    If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
    On *nix systems, readline is used if available.
sys.stdin

Здесь мы делаем демо-скрипт, используяsys.stdin, Эффективный способ перебора файловоподобного объекта заключается в использовании файловоподобного объекта в качестве итератора. Дополнительный метод для записи в стандартный вывод из этого ввода - просто использовать:sys.stdout.write

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

Распечатайте его обратно, чтобы убедиться, что он выглядит правильно:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

И перенаправить ввод в файл:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

Гольф в команду:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
Файловые дескрипторы для игры в гольф

Поскольку файловые дескрипторы дляstdin а такжеstdout 0 и 1 соответственно, мы также можем передать ихopen в Python 3 (не 2, и обратите внимание, что нам все еще нужен 'w' для записи на стандартный вывод).

Если это работает в вашей системе, это сбрит больше символов.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2io.open делает то же самое, но импорт занимает гораздо больше места:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz
Обращаясь к другим комментариям и ответам

Один комментарий предполагает''.join(sys.stdin) но это's на самом деле длиннее sys.stdin.read () - плюс Python должен создать дополнительный список в памяти (это 'шоуstr.join работает, когда нет списка) - для контраста:

''.join(sys.stdin)
sys.stdin.read()

Верхний ответ предполагает:

import fileinput

for line in fileinput.input():
    pass

Но с тех порsys.stdin реализует файловый API, включая протокол итератора, которыйТак же, как это:

import sys

for line in sys.stdin:
    pass

Другой ответделает предложить это. Просто помните, что если вы делаете это в переводчике, вынужно сделатьCtrl-D если ты'на Linux или Mac, илиCtrl-Z в Windows (послеВойти) отправить символ конца файла процессу. Кроме того, этот ответ предполагаетprint(line) - который добавляет'\n' до конца - использоватьprint(line, end='') вместо этого (если в Python 2 выпонадобитсяfrom __future__ import print_function).

Реальный вариант использования дляfileinput для чтения в серии файлов.

Попробуй это:

import sys

print sys.stdin.read().upper()

и проверьте это с:

$ echo "Hello World" | python myFile.py

Вы можете прочитать из стандартного ввода и затем сохранить входные данные в "данные" следующее:"

data = ""
for line in sys.stdin:
    data += line
 musiphil27 февр. 2019 г., 19:31
То же самое можно сделать сdata = sys.stdin.read(), без проблемы повторных конкатенаций строк.

Проблема у меня с решением

import sys

for line in sys.stdin:
    print(line)

это если ты неt передавать любые данные в stdin, он будет заблокирован навсегда. Тот'почему я люблюэтот ответ: сначала проверьте, есть ли какие-либо данные на stdin, а затем прочитайте их. Это то, что я в конечном итоге делал:

import sys
import select

# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
    help_file_fragment = sys.stdin.read()
else:
    print("No data passed to stdin", file=sys.stderr)
    sys.exit(2)
 tiktak04 нояб. 2017 г., 02:41
Однако я настоятельно рекомендую скрыть это отвратительное условие в методе.
 musiphil27 февр. 2019 г., 19:20
Этот метод серьезно ограничивает применимость программы: например, вы не можете использовать это для интерактивного ввода с терминала, потому что ввод почти никогда не будет "готовы" когдаselect называется; или вы также можете столкнуться с проблемами, если stdin подключен к файлу на медленном носителе (сеть, компакт-диск, лента и т. д.). Вы сказали, что "если ты неПередача любых данных в stdin будет заблокирована навсегда. " этопроблемано я бы сказал этосособенность, Большинство программ CLI (например,cat) работать таким образом, и они должны. EOF - единственное, от чего вы должны зависеть, чтобы определить конец ввода.

Я очень удивлен, что никто не упомянул этот хак до сих пор:

python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"

совместим как с python2, так и с python3

 musiphil27 февр. 2019 г., 19:28
Зачем использоватьreadlines которые разбиваются на линии, а затемjoin снова? Вы можете просто написатьprint(sys.stdin.read())

Python также имеет встроенные функцииinput() а такжеraw_input(), Смотрите документацию по Python подВстроенные функции.

Например,

name = raw_input("Enter your name: ")   # Python 2.x

или же

name = input("Enter your name: ")   # Python 3
 tripleee22 дек. 2015 г., 09:51
Это читает одну строку, которая неправда, о чем спрашивал ОП. Я интерпретирую вопрос какКак я могу прочитать несколько строк из дескриптора открытого файла до EOF? "
 chrisfs22 апр. 2018 г., 23:45
ОП неОн просит прочитать ввод с клавиатуры, он просит прочитать с стандартного ввода, которое обычно предоставляется участникам конкурса.
import sys

for line in sys.stdin:
    print line
 Diego Queiroz20 янв. 2019 г., 21:39
Я получаю: TypeError: 'FileWrapper» объект не повторяется.
 avp01 нояб. 2018 г., 22:22
line.rstrip (»\ П»), иначе будут отброшены все пробелы
 MilkyWay9030 окт. 2018 г., 03:09
Я предлагаю добавить объяснение этому, ответы только для комментариев не 'Это очень полезно, но спасибо за пример.
 addicted18 дек. 2018 г., 08:28
Используя этот метод, как мы узнаем, когда заканчивается поток ввода? Я хочу добавить запятую после каждой строкиexcepts для последней строки.
 brittohalloran24 мая 2018 г., 13:59
Чтобы удалить перевод строки в конце, используйтеline.rstrip()

Ваш ответ на вопрос