【问题标题】:Reading from stdin in Python 2.7.6. Sys.stdout.flush() and python -u doesn't work从 Python 2.7.6 中的标准输入读取。 Sys.stdout.flush() 和 python -u 不起作用
【发布时间】:2014-10-22 03:25:42
【问题描述】:

似乎很多人一直在努力让缓冲区和标准输入以及 stout 在多种 Python 风格中工作。我正在 Python 2.7.6 中编写一个脚本来读取标准输入,进行正则表达式匹配,并打印匹配字符串的列表。

import re, sys

barcodes=["The barcodes are:"]
curr=barcodes[0]

#iterate through stdin
for line in sys.stdin.readlines():
        #do regex match in line
        match = re.search('(?<=\:)[GATC]{6}', line.rstrip()).group(0)
        matched = 0
        #see if match has been seen before
        if (match == curr):
                matched = 1
                print "matched curr"
        else:
                for a , val in enumerate(barcodes):
                        if (match == val):
                                print str(a) + " : " + val + " barcodes[a] " + str(barcodes[a])
                                curr = barcodes[a]
                                print curr
                                matched = 1
                                print "matched iteration"
        #if match hasn't been seen before
        if (matched == 0):
                sys.stdout.write("NEW match")
                sys.stdout.flush()
                barcodes.append(match)

#print report of barcodes
for i in barcodes:
        print i

就像我之前发现的许多一样,这会等到它从 stdin 读取 EOF 块以打印任何内容,我似乎找不到任何关于如何让进程在从 stdin 读取时运行/打印的文档。

需要明确的是,无论我是否使用 -u 标志调用 Python,都会发生这种情况。

感谢您能给我的任何指导。

【问题讨论】:

  • .readlines() 将一次性读取整个文件(或标准输入)...您需要使用 .read() 并自己查找换行符。
  • 原谅我,但我已经阅读了文件对象的文档,我不清楚如何使用换行符来遍历 sys.stdin.read() 将返回的字符串。我是否应该尝试使用设定的字节数从标准输入读取,然后将字符串解析为一个列表,然后遍历每个列表,直到我读完整个文件?
  • @DanBurkhardt:你试过简单的for line in sys.stdin:吗?
  • @JohnZwinck 我没有,但这确实有效。谢谢!我想我对 sys.stdin 是一个文件对象感到困惑,所以我没有一直在寻找文件对象的方法。
  • @DanBurkhardt:不客气。我将其添加为答案,因为它似乎对您有用。

标签: python python-2.7 stdout stdin eof


【解决方案1】:

以下是一些一次读取 sys.stdin 一行的示例。他们确实需要使用 python -u 选项。

#! /usr/bin/env python

import sys

def main():
    count = 1
    while True:
        line = sys.stdin.readline()
        if line == '':
            break   #EOF encountered

        print "%3d: [%s]" % (count, line[:-1])
        count += 1


if __name__ == '__main__':
    main()

如果您使用的是 Linux / Unix,这个版本会更好,因为它可以让您进行行编辑。

#! /usr/bin/env python

import sys
import readline

def main():
    count = 1
    while True:
        try:
            line = raw_input()
            print "%3d: [%s]" % (count, line)
            count += 1
        except EOFError:
            break


if __name__ == '__main__':
    main()

【讨论】:

  • 谢谢你的这些。我之前看到过类似的解决方案,但对我来说需要使用 while True 循环似乎很疯狂。我希望有办法避免它,但在我的最终代码中,我最终使用了你的 try : except 块。
  • 我猜这是因为stdin 很特别。您可以使用for line in sys.stdin:,但随后您需要在每一行(或左右)的末尾发送一个EOF,这有点烦人。 :)
【解决方案2】:

sys.stdin 只是一个file 对象,因此如果您使用readlines(),则读取将继续,直到读取所有行。仅当您按 Ctrl+D(在 Linux 中)时才会发生这种情况。尝试逐行阅读,如下所示:

#!/usr/bin/env python
import sys,re


while True:

     line = sys.stdin.readline()
     m = re.search("end", line)
     if m:  
        break
     else:
        print "I read:" + line

【讨论】:

  • 那么标准输入的结尾在 EOF 处是否有文字“结尾”?我没想到该字符串的 re.search 会起作用。
  • "end" 只是我的例子。您应该编写代码来检测标准输入的结束。您可以根据您的要求指示标准输入的结束,例如某些输入字符串或按下 CTRL+D。
【解决方案3】:

解决方法很简单:

for line in sys.stdin:
     # process line

由于sys.stdin 是一个类似文件的对象,因此对其进行迭代会在它们可用时一次生成一行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2015-08-14
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多