for line in sys.stdin

本文探讨了Python中sys.stdin的不同读取方法及其对程序的影响。通过对比for line in sys.stdin与sys.stdin.readline()的区别,揭示了缓冲机制如何影响数据读取,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

绚丽也尘埃 » for line in sys.stdin

for line in sys.stdin

纠结一个下午和一个晚上了,我想在syslog-ng里面添加一个program destination,程序是用Python写的,结果发现file destination总是在第一时间就能收到消息,而program则没有什么动静,反复测试了好多遍都是如此。man Python,发现了Python有个’-u’参数,man是这样说的。

-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, std-out and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators (“for line in sys.stdin”) which is not influenced by this option. To work around this, you will want to use “sys.stdin.readline()” inside a “while 1:” loop.

加上’-u’之后,标准输出打印的内容很快能进入日志文件中,标准输入还是没有动静。当时没有仔细看这段说明,里面已经指出了for line in sys.stdin并不受影响,而我的代码偏偏是这样从标准输入里面读数据的。后来无意中在stackoverflow发现有一个人说这样迭代方式需要等到EOF出现才会开始执行,如果使用sys.stdin.readline()就不会有问题,测试了下发现果然是好用的。

下面两个例子可以说明问题。在终端中分别运行两个程序,第一种遍历方式会等到敲入CRTL+D才会打印输入的内容。第二种方式输入一行,回车之后就会打印这行。

?
01
02
03
04
05
06
07
08
09
10
11
12
#!/bin/env
 
import sys
 
for line in sys.stdin:
     print line,
 
line = sys.stdin.readline()
while line:
     print line,
 
     line = sys.stdin.readline()

奇怪的是,我写Hadoop Streaming Job时,一直都用for line in sys.stdin这种方式遍历,也没有出过问题。Hadoop Streaming官方文档里面的例子用的是readline这种方法。我猜这个应该是Hadoop的数据都保存在本地了,等于用cat的方式给脚本送数据,所以没有问题。

在网上查资料的时候还发现有人反馈Python使用for line in sys.stdin的一个bug:Issue1633941,就是需要输入两次CRTL+D程序才会退出。Ralph Corderoy指出这个和Python 2.6用fread导致的问题,大概的意思是fread读到的数据长度为0时,它才认为获取到了EOF。如果没有得到指定长度的数据,即使数据后面存在EOF,它也会忽略。解决办法是在循环内使用feof对stdin进行一次判断,如果结束了就立即退出。

<think>好的,用户想了解Python中'for line in sys.stdin'的功能和用法。首先,我需要回忆sys.stdin的基本概念,它是Python标准输入流,用于从命令行或其他输入源读取数据。 接下来,应该解释for循环如何逐行读取输入。需要提到sys.stdin是一个文件对象,支持迭代器协议,所以可以直接遍历。用户可能想知道常见的应用场景,比如处理管道输入或重定向文件。 然后,代码示例很重要,要展示基本的用法,比如读取每一行并处理。同时,要强调循环会一直等待输入,直到遇到EOF(比如Ctrl+D或输入结束)。 可能还需要比较input()函数和sys.stdin的区别,指出在处理大量输入时sys.stdin更高效。此外,注意事项如缓冲问题、换行符处理也要提到,避免用户遇到常见错误。 用户可能还关心如何结束输入循环,或者如何处理不同操作系统的换行符差异。需要确保示例代码简洁,并说明在Unix和Windows下的行为是否一致。 最后,生成相关问题时要覆盖相关模块如sys.stdout,其他读取方法,以及实际应用案例,帮助用户进一步学习。</think>### Python中`for line in sys.stdin`的功能和用法 在Python中,`sys.stdin`是标准输入流(standard input)的文件对象,通常用于从命令行或重定向文件中读取输入。`for line in sys.stdin`的作用是**逐行读取输入数据**,直到遇到文件结束符(EOF)。 --- #### 1. 基本功能 - **逐行读取**:通过循环遍历`sys.stdin`,每次迭代会从输入流中读取一行内容(包括换行符`\n`)并赋值给变量`line`。 - **阻塞等待输入**:如果没有输入,循环会一直等待,直到用户输入内容或程序接收到终止信号(如`Ctrl+D`或`Ctrl+Z`)[^1]。 示例代码: ```python import sys for line in sys.stdin: processed_line = line.strip() # 去除首尾空白字符 print(f"Input: {processed_line}") ``` --- #### 2. 典型应用场景 - **处理管道输入**:当程序通过管道接收其他命令的输出时(如`cat file.txt | python script.py`),可用`sys.stdin`逐行处理。 - **重定向文件输入**:运行脚本时通过`python script.py < input.txt`读取文件内容。 - **交互式输入**:手动输入多行数据时,逐行处理。 --- #### 3. 与`input()`的区别 - **性能差异**:`sys.stdin`适用于大量输入(如GB级文件),因其直接操作文件对象,效率更高;而`input()`每次调用会触发解释器交互,性能较低。 - **功能差异**:`input()`会自动去除末尾换行符,而`sys.stdin`保留换行符,需手动处理(如`line.strip()`)[^2]。 --- #### 4. 注意事项 - **换行符处理**:不同操作系统换行符可能不同(如`\n` vs `\r\n`),建议使用`line.rstrip('\n')`针对性处理。 - **缓冲机制**:`sys.stdin`默认有行缓冲,若需实时读取字符,可改用`sys.stdin.read(1)`。 --- #### 示例:统计输入行数 ```python import sys count = 0 for line in sys.stdin: count += 1 print(f"Total lines: {count}") ``` 运行方式: ```bash # 从文件输入 python script.py < data.txt # 从管道输入 cat data.txt | python script.py ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值