从subprocess.Popen.stdout读取多行
我修改了Fred Lundh的Python标准库的源代码。原来的代码是用popen2来和子进程沟通,但我把它改成了用subprocess.Popen(),具体如下。
import subprocess
import string
class Chess:
"Interface class for chesstool-compatible programs"
def __init__(self, engine = "/opt/local/bin/gnuchess"):
proc=subprocess.Popen([engine],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
self.fin, self.fout = proc.stdin, proc.stdout
s = self.fout.readline() <--
print s
if not s.startswith("GNU Chess"):
raise IOError, "incompatible chess program"
def move(self, move):
...
my = self.fout.readline() <--
...
def quit(self):
self.fin.write("quit\n")
self.fin.flush()
g = Chess()
print g.move("a2a4")
print g.move("b2b3")
g.quit()
看起来运行得还不错,但gnuchess会打印出多行信息,而用self.fout.readline()只显示一行。
Thinking... ... R N B Q K B N R
我该怎么才能获取多行信息呢?readlines()这个方法似乎不管用。
补充说明
我测试了movieyoda的代码,但它不管用。我觉得只有readline()应该能工作,而readlines()和read()不行,因为后者不知道什么时候该停止读取,只有readline()能做到这一点。
2 个回答
0
我会直接读取它输出的内容,等到这个进程结束时,子进程模块会帮你处理后面的清理工作。你可以这样做 -
l = list()
while True:
data = proc.stdout.read(4096)
if not data:
break
l.append(data)
file_data = ''.join(l)
这些都是用来替代 self.fout.readline()
的方法。我还没试过,但应该可以处理多行内容。
2
要和gnuchess进行互动,我会使用pexpect这个工具。
import pexpect
import sys
game = pexpect.spawn('/usr/games/gnuchess')
# Echo output to stdout
game.logfile = sys.stdout
game.expect('White')
game.sendline('a2a4')
game.expect('White')
game.sendline('b2b3')
game.expect('White')
game.sendline('quit')