如何读取stdin?一些代码高尔夫挑战需要使用stdin进行输入。


当前回答

我对解决方案的问题

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)

其他回答

Python还具有内置函数input()和raw_input()。请参阅内置函数下的Python文档。

例如

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

or

name = input("Enter your name: ")   # Python 3

从Python 3.8开始,您可以使用赋值表达式:

while (line := input()):
    print(line)

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替换为here字符串:

./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 -

对于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

其他人提出的答案:

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

更新从评论中可以看出,在python2上可能只涉及缓冲区,因此在发出打印调用之前,您最终会等待缓冲区填充或EOF。