你如何从Python的标准input读取?

我试图做一些代码高尔夫的挑战,但他们都需要input从stdin 。 我如何在Python中获得?

您可以使用fileinput模块:

 import fileinput for line in fileinput.input(): pass 

fileinput将遍历input中指定为命令行参数中给定的文件名的所有行,或者在没有提供参数的情况下循环input标准input。

有几种方法可以做到这一点。

  • sys.stdin是一个类似文件的对象,如果你想读取所有内容,或者你想读取所有内容并自动将其拆分为新行,可以在其上调用函数readreadlines 。 (你需要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程序,如catgrepsed

你如何从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 

文件描述符为打高尔夫球

由于stdinstdout文件描述符分别为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上执行Ctrld ,或者在Windows上执行Ctrlz (在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\nreplace它们。

如果检测到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