【问题标题】:subprocess works in Python 2 but not in Python 3subprocess 在 Python 2 中有效,但在 Python 3 中无效
【发布时间】:2015-05-16 19:25:49
【问题描述】:

此子流程代码在 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()

【问题讨论】:

  • 当它不起作用时,会发生什么?你有例外吗?如果是这样,请包括回溯。如果您有其他行为,请描述它。

标签: python subprocess


【解决方案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 接受exit 命令,则无需调用gnuchess.terminate()

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多