sys.stdin 读取什么内容?

35

我知道如何打开文件,并使用Python的预定义函数进行操作。但sys.stdin是如何工作的?

for something in sys.stdin:
    some stuff here

lines = sys.stdin.readlines()

以上两个不同的sys.stdin用法有什么区别?它读取信息的位置在哪里?是通过键盘还是我们仍然需要提供一个文件?


2
你熟悉input()吗?无论input()从哪里获取输入,都是通过sys.stdin实现的。这可能是终端,也可能是来自文件,或者来自另一个程序的输出,或者取决于你如何调用程序。 - user2357112
6个回答

43

那么你已经使用了Python的“预先构建的函数”,可能是像这样:

file_object = open('filename')
for something in file_object:
    some stuff here

通过在文件对象上调用迭代器,这将返回文件的下一行。这将读取文件。

您也可以使用以下内容:

file_object = open('filename')
lines = file_object.readlines()

该函数从当前文件位置读取行并将其存储到列表中。

现在,sys.stdin只是另一个文件对象,在您的程序启动之前由Python打开。您对该文件对象的操作取决于您,但它与任何其他文件对象并没有真正的区别,只是您不需要使用open

for something in sys.stdin:
    some stuff here

将会迭代标准输入,直到到达文件结尾。这个也是这样的:

lines = sys.stdin.readlines()

您的第一个问题实际上是关于不同文件对象使用方式的。

其次,它从哪里读取?它正在从文件描述符0(零)读取。在Windows上,它是文件句柄0(零)。文件描述符/句柄0默认连接到控制台或tty,因此实际上它正在从键盘读取。然而,它可以通过类似这样的语法进行重定向,通常由shell(如bash或cmd.exe)执行:

myprog.py < input_file.txt 

这会改变文件描述符0的行为,使其读取一个文件而不是键盘输入。在UNIX或Linux系统中,这可以使用底层调用dup2()实现。有关重定向的更多信息,请阅读您的shell文档(或者如果您足够勇敢,可以查看man dup2)。


3
Python 3 中的文本流。 - cdarke

7
它正在从标准输入读取 - 应该由键盘提供流数据形式。不需要提供文件,但是您可以使用redirection将文件用作标准输入。在Python中,readlines()方法读取整个流,然后在换行符处拆分它,并创建每行的列表。
lines = sys.stdin.readlines()

上面创建了一个名为lines的列表,其中每个元素都将是一行(由换行符确定)。
您可以在Python教程的输入和输出部分中阅读更多相关信息。
如果您想提示用户输入,请使用input()方法(在Python 2中,请使用raw_input()):
user_input = input('Please enter something: ')
print('You entered: {}'.format(user_input))

当我使用sys.stdin.readlines()而不是sys.stdin时,标准输入如何被读取?第二个方法是否逐个单词读取?我仍然感到困惑。 - Vimzy

7
为了了解sys.stdin的工作原理,请按照以下步骤操作:
创建一个简单的Python脚本,我们将其命名为“readStdin.py”:
import sys
lines = sys.stdin.readlines()
print (lines)

现在打开控制台,并输入以下内容:

echo "line1 line2 line3" | python readStdin.py
['"line1 line2 line3" \n']

因此,脚本已将输入读入列表中(名为“lines”),包括由“echo”生成的换行符。就是这样。


4

据我所知,sys.stdin.read() 方法接受用户的输入行,直到遇到特殊字符,如回车键,并接着 Ctrl + D,然后将输入存储为字符串。

Ctrl + D 作为停止信号。

例如:

import sys

input = sys.stdin.read()
print(input)
tokens = input.split()
a = int(tokens[0])
b = int(tokens[1])
print(a + b)

运行程序后输入两个以空格分隔的数字,完成后按一到两次 Control + D,即可得到这两个数字的和。


1
在完成文本输入后,按Enter然后按Ctrl+Z --> 在Windows上 - Igor Micev

3
for something in sys.stdin:
    some stuff here

上面的代码不能像您期望的那样工作,因为sys.stdin是一个文件句柄 - 它是指向stdin的文件句柄。它将不会到达some stuff here这一行。

lines = sys.stdin.readlines()

当上述脚本在交互式shell中运行时,它会阻塞执行直到用户按下Ctrl-D,这表示输入的结束。

那么,当我使用sys.stdin.readlines()而不是sys.stdin时,标准输入会有什么不同?第二个方法是否逐个读取每个单词?我仍然感到困惑。 - Vimzy

1

它将逐行读取源文件。它在在线评测系统中被广泛使用。

例如:假设我们只有一个数字2将在文件中使用。

import sys

if __name__ == "__main__":
    n = int(sys.stdin.readline().strip())

逐行读取文件意味着只读取数字 2(在此情况下仅有一行)。使用strip函数去除不需要的空格或其他指定字符。这将导致n = (整数)2

如果我们有一个包含两行的文件:

1
2

那么,sys.stdin.readline().strip()会将其转换为一行(一个名为n的列表)有两个元素12。然后我们现在不能使用int转换器,但我们可以使用int(n[0])int(n[1])代替。


1
我不明白你所说的“将其转换为一行(一个名为n的列表)”是什么意思。.readline()返回一个字符串,而.strip()将其保留为字符串,你是指.split()或可能只是stdin.readlines()吗? - Tadhg McDonald-Jensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接