如何读取stdin?一些代码高尔夫挑战需要使用stdin进行输入。
当前回答
有os.读取(0,x)它从表示stdin的0读取xbytes。这是一个无缓冲的读取,比sys.stdin.read()更低级
其他回答
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 -
import sys
for line in sys.stdin:
print(line)
请注意,这将在末尾包含一个换行符。要删除末尾的换行符,请使用@brittohaloran所说的line.rstrip()。
使用文件输入模块:
import fileinput
for line in fileinput.input():
pass
fileinput将循环通过输入中指定为命令行参数中给定的文件名的所有行,如果没有提供参数,则循环通过标准输入。
注意:行将包含尾随换行符;要删除它,请使用line.rstrip()。
如何在Python中读取stdin?我正在尝试进行一些代码高尔夫挑战,但它们都需要从stdin获取输入。我如何在Python中实现这一点?
您可以使用:
sys.stdin-类似文件的对象-调用sys.stdin.read()读取所有内容。input(prompt)-将可选提示传递给输出,它从stdin读取到第一个换行符,并将其删除。您必须重复这样做才能获得更多的行,在输入结束时会引发EOFError。(可能不适合打高尔夫球。)在Python 2中,这是raw_input(提示)。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。
与Python 2和3、Windows、Unix兼容的快速sys.stdin示例
例如,如果将数据传输到stdin,则只需从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(在Python 2中使用raw_input)和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
下面是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.
内置函数,输入(Python 2中的raw_input)
内置函数输入从标准输入读取到换行符,换行符被删除(补充打印,默认情况下添加换行符)。这会发生,直到它得到EOF(文件结束),此时它会引发EOFError。
因此,这里介绍了如何使用Python 3中的输入(或Python 2中的raw_input)从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
同样,输入读取到换行符,并从该行中删除它。print将添加新行。因此,当它们都修改输入时,它们的修改会取消。(因此,它们本质上是彼此的补充。)
当输入得到文件结尾字符时,它会引发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
下面是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制作了一个演示脚本。对类似文件的对象进行迭代的有效方法是使用类似于文件的对象作为迭代器。从该输入写入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,因此我们也可以将它们传递到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
另一个答案确实表明了这一点。请记住,如果您在解释器中执行此操作,那么如果您在Linux或Mac上,则需要执行Ctrl-d,或者在Windows上执行Ctrl-z(在Enter之后),以将文件结尾字符发送到进程。此外,该答案建议print(line)-在结尾处添加一个“\n”-改用print(line,end=“”)(如果在Python 2中,则需要使用__future_import print_function)。
fileinput的实际用例是读取一系列文件。
试试看:
import sys
print sys.stdin.read().upper()
并通过以下方式进行检查:
$ echo "Hello World" | python myFile.py
推荐文章
- “克隆”行或列向量
- 在python shell中按方向键时看到转义字符
- 在pip install中方括号是什么意思?
- 使用Matplotlib以非阻塞的方式绘图
- 使用sklearn缩放Pandas数据框架列
- 如何创建关键或附加一个元素的关键?
- virtualenv的问题-无法激活
- 是否可以使用scikit-learn K-Means聚类来指定自己的距离函数?
- 如何在Python中删除文本文件的文件内容?
- 一个干净、轻量级的Python扭曲的替代品?
- 在Python中从字符串中移除所有非数字字符
- 在Python中,如何以排序的键顺序遍历字典?
- Python中的多行f-string
- 批量归一化和退出的排序?
- Python中的“@=”符号是什么意思?