问题:您如何从stdin阅读?
我正在尝试挑战一些代码挑战,但是所有这些挑战都需要从输入stdin
。我如何在Python中得到它?
回答 0
您可以使用以下fileinput
模块:
import fileinput
for line in fileinput.input():
pass
fileinput
将在输入中指定为命令行参数中指定的文件名的所有行,如果没有提供参数则返回标准输入。
注意:line
将包含尾随换行符;删除它使用line.rstrip()
回答 1
有几种方法可以做到。
sys.stdin
是一个类似于文件的对象,可以在其上调用函数,read
或者readlines
如果要读取所有内容,或者要读取所有内容并自动按换行符将其拆分,则可以在其上调用。(您需要使它import sys
起作用。)如果您实际上只想阅读命令行选项,则可以通过sys.argv列表访问它们。
您可能还会发现有关I / O和Python的Wikibook这篇文章也是有用的参考。
回答 2
import sys
for line in sys.stdin:
print(line)
请注意,这将在末尾包含换行符。要最后删除换行符,请使用line.rstrip()
@brittohalloran所说的。
回答 3
Python还具有内置函数input()
和raw_input()
。请参阅“ 内置函数”下的Python文档。
例如,
name = raw_input("Enter your name: ") # Python 2.x
要么
name = input("Enter your name: ") # Python 3
回答 4
来自学习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.
回答 5
您如何从Python的stdin中读取信息?
我正在尝试进行一些代码挑战,但是它们都要求输入来自stdin。我如何在Python中得到它?
您可以使用:
sys.stdin
-类似于文件的对象-调用sys.stdin.read()
以读取所有内容。input(prompt)
-向其传递一个可选的提示以输出,它从stdin读取直到第一个换行符,然后将其剥离。您必须重复执行此操作才能获得更多行,在输入结束时会引发EOFError。(可能不适用于打高尔夫球。)在Python 2中,这是rawinput(prompt)
。open(0).read()
-在Python 3中,内置函数open
接受文件描述符(代表操作系统IO资源的整数),而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兼容的快速示例
例如,如果您将数据通过管道传输到stdin,则只需要read
from sys.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读取的方法-因此我们创建了一个称为stdindemo.py的Python模块:
$ 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
或者我们可以从stdin重定向文件:
$ 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
。迭代类似文件的对象的有效方法是使用类似文件的对象作为迭代器。从此输入写入stdout的补充方法是简单地使用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 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)
-最终会增加a-的'\n'
使用print(line, end='')
(如果在Python 2中,则需要from __future__ import print_function
)。
真正的用例fileinput
是读取一系列文件。
回答 6
其他人提出的答案:
for line in sys.stdin:
print line
是非常简单且具有Python风格的代码,但必须注意,脚本将等到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。
回答 7
这会将标准输入回显到标准输出:
import sys
line = sys.stdin.readline()
while line:
print line,
line = sys.stdin.readline()
回答 8
如果使用sys.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程序,例如cat
,grep
和sed
。
回答 9
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
./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 -
回答 10
以下代码芯片将为您提供帮助(它将把所有的stdin阻塞读EOF
入到一个字符串中):
import sys
input_str = sys.stdin.read()
print input_str.split()
回答 11
令我惊讶的是,到目前为止,还没有人提到此黑客:
python -c "import sys; set(map(sys.stdout.write,sys.stdin))"
在python2中,您可以删除set()
呼叫,但是它将以任何一种方式发出提示
回答 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
从Windows读取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
我使用以下方法,它从stdin返回一个字符串(我将其用于json解析)。它适用于Windows上的管道和提示(尚未在Linux上进行测试)。提示时,两个换行符指示输入结束。
def get_from_stdin():
lb = 0
stdin = ''
for line in sys.stdin:
if line == "\n":
lb += 1
if lb == 2:
break
else:
lb = 0
stdin += line
return stdin
回答 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上尝试了一个很大的文件(遵循别人的建议),但出于上述原因(长时间未发生任何事情),我不建议这样做。
我最终得到了一个稍微多一点的pythonic解决方案(它适用于更大的文件):
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
回答 19
对于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
回答 20
有
os.read(0, x)
从0表示标准输入读取xbytes。这是一个无缓冲的读取,比sys.stdin.read()的级别低。
回答 21
使用-c
命令时,以一种棘手的方式,您无需阅读stdin
(在某些情况下更为灵活),就可以通过将sell命令放在以引号开头的括号内的引号中来将Shell脚本命令传递给python命令$
。
例如
python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"
这将计算goldendict的历史记录文件中的行数。