subprocess在Python 2中工作,但在Python 3中不工作

时间:2015-05-16 19:25:50

标签: python subprocess

这个子流程代码在Python 2中完美运行,但在Python 3中不起作用。我该怎么办?

谢谢,

import subprocess

gnuchess = subprocess.Popen('gnuchess', stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)

# Python 3 strings are Unicode and must be encoded before writing to a pipe (and decoded after reading)
gnuchess.stdin.write('e4\n'.encode())

while True:   
L = gnuchess.stdout.readline().decode()
L = L[0:-1]
print(L)
if L.startswith('My move is'):
    movimiento = L.split()[-1]
    break

print(movimiento)

gnuchess.stdin.write('exit\n'.encode())

gnuchess.terminate()

1 个答案:

答案 0 :(得分:1)

差异的最可能原因是缓冲行为的变化,设置bufsize=1以启用行缓冲。

为避免手动编码/解码,您可以使用universal_newlines=True启用文本模式(使用locale.getpreferredencoding(False)字符编码解释数据)。

#!/usr/bin/env python3
from subprocess import Popen, PIPE, DEVNULL

with Popen('gnuchess', stdin=PIPE, stdout=PIPE, stderr=DEVNULL,
           bufsize=1, universal_newlines=True) as gnuchess:
    print('e4', file=gnuchess.stdin, flush=True)
    for line in gnuchess.stdout:
        print(line, end='')
        if line.startswith('My move is'):            
            break
    print('exit', file=gnuchess.stdin, flush=True)

如果gnuchess.terminate()接受gnuchess命令,则无需致电exit

在“我的移动是”短语之前读取线条似乎很脆弱。调查gnuchess是否提供具有更严格输出分离的批处理模式。