Python,为什么我无法重写Popen.stdout

0 投票
1 回答
650 浏览
提问于 2025-04-16 14:31

为什么我可以用自己的类来覆盖 sys.stdout,但不能覆盖 subprocess.Popen.stdout?如果可以覆盖,请告诉我怎么做……

我正在做一个图形用户界面(GUI)项目,我想要实时打印其他程序的输出,而不是等所有事情都完成后再打印。

当我覆盖 sys.stdout 时,我是这样做的:

class MyStdOut :
  def __init__(self) : self.text = ""
  def write(self, string) : self.text += string

这里有一个程序 'pyscript.py'

import os

def main() :
  for i in range(10) :
    print i
    os.system('sleep 0.1') ## this is just to make some delay, i did also 3 loops

if __name__ == '__main__' : main()

这是主程序:

import subprocess as sub

def main() :
  popen = sub.Popen('./pyscript.py', stdout=sub.PIPE)
  for line in popen.stdout : print 'Line :', line
  print 'Main done'

if __name__ == '__main__' : main()

但这仍然不是“实时”的,我得到的输出都是在程序结束后才显示的。

我也试过使用 communicate,但结果还是一样。

在我的实际程序中,我需要在文本视图(GUI GTK+)上打印其他程序的输出。我怀疑 subprocess.stdout 必须是一个文件,但当我尝试创建一个继承自 IOBase 的类时也遇到了错误。

大家都说这是可能的,但我尝试了很多不同的方法都没有成功。

1 个回答

2

你可以通过以下方式实现相同的效果:

p = Popen(args, ..., stdout=subprocess.PIPE)
for line in p.stdout:
   print line

这里的 p.stdout 就像一个管道(PIPE),你可以在数据到达时立即从中读取。虽然不是严格的实时,因为会有一些缓冲的影响,但这仍然是一个可行的替代方案。

撰写回答