你如何从Python的标准input读取?
我试图做一些代码高尔夫的挑战,但他们都需要input从stdin
。 我如何在Python中获得?
您可以使用fileinput
模块:
import fileinput for line in fileinput.input(): pass
fileinput
将遍历input中指定为命令行参数中给定的文件名的所有行,或者在没有提供参数的情况下循环input标准input。
有几种方法可以做到这一点。
-
sys.stdin
是一个类似文件的对象,如果你想读取所有内容,或者你想读取所有内容并自动将其拆分为新行,可以在其上调用函数read
或readlines
。 (你需要import sys
才能工作。) -
如果你想提示用户input,你可以在Python 2.X中使用
raw_input
,然后在Python 3中input
。 -
如果你只是想读取命令行选项,你可以通过sys.argv列表来访问它们。
您可能会发现这篇关于Python中的I / O的Wikibook文章也是一个有用的参考。
import sys for line in sys.stdin: print line
Python也有内build函数input()
和raw_input()
。 请参阅内置函数下的Python文档。
例如,
name = raw_input("Enter your name: ") # Python 2.x
要么
name = input("Enter your name: ") # Python 3
这里是学习Python :
import sys data = sys.stdin.readlines() print "Counted", len(data), "lines."
在Unix上,您可以通过执行以下操作来testing它:
% cat countlines.py | python countlines.py Counted 3 lines.
在Windows或DOS上,你可以这样做:
C:\> type countlines.py | python countlines.py Counted 3 lines.
其他人提出的答案是:
for line in sys.stdin: print line
是非常简单和pythonic,但必须注意,脚本将等到EOF之前开始迭代的input行。
这意味着tail -f error_log | myscript.py
tail -f error_log | myscript.py
不会像预期的那样处理行。
这种用例的正确脚本是:
while 1: try: line = sys.stdin.readline() except KeyboardInterrupt: break if not line: break print line
UPDATE
从注释中已经清除了,只有在python 2中可能会涉及到缓冲,所以在打印调用发出之前,您最终会等待缓冲区填满或EOF。
这将回应标准input到标准输出:
import sys line = sys.stdin.readline() while line: print line, line = sys.stdin.readline()
如果至less有一个参数存在,则可以使用sys.stdin
构build所有的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程序,如cat
, grep
和sed
。
你如何从Python的标准input读取?
我试图做一些代码高尔夫的挑战,但他们都需要input从标准input。 我如何在Python中获得?
你只需要从sys.stdin
read
。
TLDR:兼容Python 2和3,Windows,Unix
假设你有一个文件, inputs.txt
,我们可以接受该文件并将其写回:
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
较长的答案
这是一个完整的,易于复制的演示,使用两种方法,内置函数, input
(在Python 2中使用raw_input
)和sys.stdin
。 数据是未修改的,所以处理是非操作的。
首先,我们来创build一个input文件:
$ python -c "print('foo\nbar\nbaz')" > inputs.txt
使用我们已经看到的代码,我们可以检查我们是否创build了这个文件:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt foo bar baz
以下是Python 3中sys.stdin.read
的帮助:
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.
内build函数, input
(Python 2中的raw_input
)
内置函数input
从标准input
读取到新行,该行被剥离(补充print
,默认添加一个换行符)。直到获得EOF(文件结束),此时会引发EOFError
。
因此,下面是如何在Python 3中使用input
(或Python 2中的raw_input
)从stdin读取 – 因此我们创build了一个我们称为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,他们的修改取消。 (所以他们基本上是彼此的补充。)
而当input
获得文件结束符时,会引发EOFError,我们忽略它然后退出程序。
在Linux / Unix上,我们可以从cat:
$ cat inputs.txt | python -m stdindemo foo bar baz
或者我们可以redirectstdin的文件:
$ python -m stdindemo < inputs.txt foo bar baz
我们也可以作为脚本执行模块:
$ python stdindemo.py < inputs.txt foo bar baz
以下是Python 3内置input
的帮助:
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
制作一个演示脚本。 迭代类文件对象的有效方法是使用类文件对象作为迭代器。 从这个input写入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)
并将inputredirect到文件中:
$ 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,所以我们也可以通过那些在Python 3中open
(不是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
处理其他意见和答案
一个评论build议''.join(sys.stdin)
但实际上比sys.stdin.read()长 – 加上Python必须在内存中创build一个额外的列表(这是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
另一个答案确实表明 请记住,如果您是在解释器中执行此操作,则需要在Linux或Mac上执行Ctrl – d ,或者在Windows上执行Ctrl – z (在Enter之后),将文件结尾字符发送到处理。 另外,这个答案build议print(line)
– 在最后使用print(line, end='')
来代替(如果在Python 2中,您将需要from __future__ import print_function
)。
fileinput
的真正用例是用于读取一系列文件。
PS我花了很大的努力试图使这些演示跨平台的工作。 Python是一致的,但shell条目不是很灵活。 但是,让Windows和Linux上的用户都可以访问它,这对我来说很重要。 让我知道如果你有Windows的问题。
下面的代码芯片将帮助您:
input_str = sys.stdin.read() print input_str.split()
尝试这个:
import sys print sys.stdin.read().upper()
并检查它:
$ echo "Hello World" | python myFile.py
您可以从stdin读取数据 ,然后将input存储到“data”中 ,如下所示:
data = "" for line in sys.stdin: data += line
从sys.stdin
中读取 ,但要读取Windows上的二进制数据 ,则需要特别小心,因为sys.stdin
在文本模式下打开,并且\r\n
用\r\n
replace它们。
如果检测到Windows + Python 2,解决scheme是将模式设置为二进制,而在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()
我非常惊讶到目前为止还没有人提到这个黑客行为:
python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"
兼容python2和python3
我有一些问题,当得到这个工作,阅读套接字的套接字。 当套接字closures时,它开始在一个活动循环中返回空string。 所以这是我的解决scheme(我只在Linux中testing,但希望它可以在所有其他系统中工作)
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
关于这个:
for line in sys.stdin:
我只是尝试了python 2.7(遵循其他人的build议)为一个非常大的文件,我不推荐它,正是由于上述原因(长期没有发生)。
我结束了一个稍微pythonic的解决scheme(并在更大的文件上工作):
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
我有解决的问题
import sys for line in sys.stdin: print(line)
如果你不把任何数据传递给标准input,它将永远阻塞。 这就是为什么我喜欢这个答案 :首先检查标准input是否有一些数据,然后读取它。 这就是我最终做的事情:
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)
一种select是使用inputfunction,如下所示。 如果您不确定数据types,也有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