从 subprocess.Popen.stdout 读取多行

发布于 2024-09-26 09:11:51 字数 1108 浏览 5 评论 0原文

我修改了 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() 之外,人们不知道何时停止阅读。

I modified the source code from Fred Lundh's Python Standard Library.
The original source uses popen2 to communicate to subprocess, but I changed it to use subprocess.Popen() as follows.

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()

It seems to run OK, but the gnuchess prints out multiple lines of messages as follows, but with self.fout.readline() it only shows one line.

Thinking...
... 
R N B Q K B N R 

How do I get multiple lines of message? readlines() method doesn't seem to work.

ADDED

I tested the code from movieyoda, but it doesn't work.
I think it's just correct that only readline() should work, not readlines() and read(), as one doesn't know when to stop reading except for the readline().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不必你懂 2024-10-03 09:11:51

要与 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')

To interact with gnuchess, I'd use 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')
‘画卷フ 2024-10-03 09:11:51

我只会在它到达时读取它的输出。当进程终止时,子进程模块将为您清理工作。你可以做这样的事情 -

l = list()
while True:
    data = proc.stdout.read(4096)
    if not data:
        break
    l.append(data)
file_data = ''.join(l)

所有这些都是 self.fout.readline() 的替代品。没试过。但应该处理多行。

I would just read it's output as it arrives. When the process dies, the subprocess module will take care of cleaning things up for you. You could do something like this -

l = list()
while True:
    data = proc.stdout.read(4096)
    if not data:
        break
    l.append(data)
file_data = ''.join(l)

All of this is a replacement for self.fout.readline(). Have not tried it. But should handle multiple lines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文