Как вы читаете со стандартного ввода?
Я пытаюсь выполнить некоторые из code golf, но все они требуют ввода, который нужно взять из stdin
. Как я могу получить это в Python?
Ответы
Ответ 1
Вы можете использовать модуль fileinput
:
import fileinput
for line in fileinput.input():
pass
fileinput
будет проходить по всем строкам ввода, указанным как имена файлов, заданные в аргументах командной строки, или стандартный ввод, если аргументы не предоставлены.
Примечание: line
будет содержать завершающий символ новой строки; чтобы удалить его используйте line.rstrip()
Ответ 2
Есть несколько способов сделать это.
-
sys.stdin
- это файл-подобный объект, на котором вы можете вызывать функции read
или readlines
если вы хотите прочитать все или хотите все прочитать и разделить на новую строку автоматически. (Для этого вам нужно import sys
.)
-
Если вы хотите raw_input
пользователя для ввода, вы можете использовать raw_input
в Python 2.X и просто input
в Python 3.
-
Если вы просто хотите прочитать параметры командной строки, вы можете получить к ним доступ через список sys.argv.
Вы, вероятно, найдете эту статью в Википедии о вводе-выводе в Python также полезной ссылкой.
Ответ 3
import sys
for line in sys.stdin:
print(line)
Обратите внимание, что в конце будет добавлен символ новой строки. Чтобы удалить перевод строки в конце, используйте line.rstrip()
, как сказал @brittohalloran.
Ответ 4
Python также имеет встроенные функции input()
и raw_input()
. См. Документацию Python в Встроенные функции.
Например,
name = raw_input("Enter your name: ") # Python 2.x
или
name = input("Enter your name: ") # Python 3
Ответ 5
Здесь из Learning 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.
Ответ 6
Ответ, предложенный другими:
for line in sys.stdin:
print line
очень прост и pythonic, но следует отметить, что script будет ждать до EOF перед началом итерации по строкам ввода.
Это означает, что tail -f error_log | myscript.py
не будет обрабатывать строки, как ожидалось.
Правильный script для такого варианта использования:
while 1:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
break
if not line:
break
print line
UPDATE
Из комментариев было очищено то, что на python 2 может быть только буферизация, так что вы в конечном итоге ожидаете заполнения буфера или EOF до того, как выйдет запрос на печать.
Ответ 7
Как вы читаете со стандартного ввода в Python?
Я пытаюсь выполнить некоторые задачи кода, но все они требуют ввода от stdin. Как мне получить это в Python?
Вы можете использовать:
sys.stdin
- Файловый объект - вызовите sys.stdin.read()
, чтобы прочитать все.
input(prompt)
- передать ему необязательный запрос на вывод, он читает от стандартного ввода до первой новой строки, которую удаляет. Вам придется делать это несколько раз, чтобы получить больше строк, в конце ввода это вызывает EOFError. (Вероятно, не подходит для игры в гольф.) В Python 2 это rawinput(prompt)
.
open(0).read()
- В Python 3 встроенная функция open
принимает файловые дескрипторы (целые числа, представляющие ресурсы ввода-вывода операционной системы), а 0 - дескриптор stdin
. Он возвращает файл-подобный объект, такой как sys.stdin
- вероятно, ваш лучший выбор для игры в гольф. В Python 2 это io.open
.
open('/dev/stdin').read()
- аналогично open(0)
, работает на Python 2 и 3, но не на Windows (или даже Cygwin).
fileinput.input()
- возвращает итератор над строками во всех файлах, перечисленных в sys.argv[1:]
, или stdin, если не указан. Используйте как ''.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
Мы видим, что sys.stdin
находится в текстовом режиме по умолчанию:
>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
пример файла
Скажем, у вас есть файл, inputs.txt
, мы можем принять этот файл и записать его обратно:
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
Более длинный ответ
Здесь полная, легко воспроизводимая демонстрация с использованием двух методов: встроенной функции, input
(используйте raw_input
в Python 2) и sys.stdin
. Данные не изменены, поэтому обработка не является операцией.
Для начала давайте создадим файл для ввода:
$ 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.
Встроенная функция, input
(raw_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
И давайте распечатаем его обратно, чтобы убедиться, что мы ожидаем:
$ 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
Или мы можем просто перенаправить файл из стандартного ввода:
$ python -m stdindemo < inputs.txt
foo
bar
baz
Мы также можем выполнить модуль как скрипт:
$ python stdindemo.py < inputs.txt
foo
bar
baz
Вот справка по встроенному 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' для записи в stdout).
Если это работает в вашей системе, это сбрит больше символов.
$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo
Python 2 io.open
также делает это, но импорт занимает гораздо больше места:
$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt
foo
bar
baz
Обращение к другим комментариям и ответам
Один комментарий предлагает ''.join(sys.stdin)
для игры в гольф, но на самом деле он длиннее, чем 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 (после Enter), чтобы отправить символ конца файла процессу. Кроме того, в этом ответе предлагается print(line)
- который добавляет '\n'
к концу - используйте вместо него print(line, end='')
(если в Python 2 вам понадобится from __future__ import print_function
).
Реальный вариант использования fileinput
предназначен для чтения в серии файлов.
Ответ 8
Это приведет к стандартному входу стандартного вывода:
import sys
line = sys.stdin.readline()
while line:
print line,
line = sys.stdin.readline()
Ответ 9
Основываясь на всех anwers с помощью 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 script будет вести себя как многие программы GNU/Unix, такие как cat
, grep
и sed
.
Ответ 10
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'
2. Использование аргумента имени файла
echo 'foo bar' > my-file.data
./above-script.py my-file.data
3. Использование stdin
через специальное имя файла -
echo 'foo bar' | ./above-script.py -
Ответ 11
Следующий чип кода поможет вам (он будет читать все блокировки stdin до EOF
в одну строку):
import sys
input_str = sys.stdin.read()
print input_str.split()
Ответ 12
Попробуйте следующее:
import sys
print sys.stdin.read().upper()
и проверьте его с помощью:
$ echo "Hello World" | python myFile.py
Ответ 13
Вы можете читать из stdin, а затем хранить входы в "данные" следующим образом:
data = ""
for line in sys.stdin:
data += line
Ответ 14
Считайте из 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()
Ответ 15
Я очень удивлен, что никто пока не упоминал об этом хаке:
python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"
совместим с python2 и python3
Ответ 16
Проблема с решением
import sys
for line in sys.stdin:
print(line)
заключается в том, что если вы не передадите какие-либо данные в 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)
Ответ 17
У меня возникли некоторые проблемы при работе с ним для чтения через сокеты, подключенные к нему. Когда сокет закрылся, он начал возвращать пустую строку в активном цикле. Так что это мое решение для меня (которое я тестировал только в 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
Ответ 18
Относительно этого:
for line in sys.stdin:
Я просто попробовал это на python 2.7 (после какого-то другого предложения) для очень большого файла, и я не рекомендую его именно по причинам, упомянутым выше (ничего не происходит в течение длительного времени).
В итоге у меня появилось несколько более питоническое решение (и оно работает с большими файлами):
with open(sys.argv[1], 'r') as f:
for line in f:
Затем я могу запустить script локально как:
python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
Ответ 19
n = int(raw_input())
for i in xrange(n):
name, number = raw_input().split()
Ответ 20
Один из вариантов - использовать функцию ввода, как показано ниже. Существует также метод raw_input, если вы не уверены в типе данных.
#!/usr/bin/env python
number = input("Please enter a number : ")
print("Entered number is %d" % number)
Запуск программы:
python test1.py
Please enter a number : 55
Entered number is 55
Ссылка: http://www.python-course.eu/input.php
Ответ 21
Существует os.read(0, x)
который читает xbytes из 0, что представляет собой стандартный ввод. Это небуферизованное чтение, более низкий уровень, чем sys.stdin.read()
Ответ 22
Для Python 3 это будет:
# Filename e.g. cat.py
import sys
for line in sys.stdin:
print(line, end="")
Это в основном простая форма cat (1), так как она не добавляет символ новой строки после каждой строки. Вы можете использовать это (после того, как Вы отметили исполняемый файл, используя chmod +x cat.py
например:
echo Hello | ./cat.py
Ответ 23
При использовании команды -c
в качестве хитрого способа вместо чтения стандартного stdin
(и в некоторых случаях более гибкого) вы можете также передать команду сценария оболочки в команду python, поместив команду sell в кавычки в скобках, начинающихся с знак $
.
например
python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"
Это будет подсчитывать количество строк из файла истории goldendict.