gpt4 book ai didi

python - 使用 Python 进行交互式输入/输出

转载 作者:IT老高 更新时间:2023-10-28 22:12:23 28 4
gpt4 key购买 nike

我有一个与用户交互的程序(就像一个 shell),我想使用 Python 子进程模块交互地运行它。这意味着,我希望能够写入标准输入并立即从标准输出中获取输出。我尝试了这里提供的许多解决方案,但似乎没有一个能满足我的需求。

我写的代码是基于 Running an interactive command from within Python .

import Queue
import threading
import subprocess
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()

def getOutput(outQueue):
outStr = ''
try:
while True: # Adds output from the queue until it is empty
outStr += outQueue.get_nowait()

except Queue.Empty:
return outStr

p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize = 1)
#p = subprocess.Popen("./a.out", stdin=subprocess.PIPE, stout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)

outQueue = Queue()
errQueue = Queue()

outThread = Thread(target=enqueue_output, args=(p.stdout, outQueue))
errThread = Thread(target=enqueue_output, args=(p.stderr, errQueue))

outThread.daemon = True
errThread.daemon = True

outThread.start()
errThread.start()

p.stdin.write("1\n")
p.stdin.flush()
errors = getOutput(errQueue)
output = getOutput(outQueue)

p.stdin.write("5\n")
p.stdin.flush()
erros = getOutput(errQueue)
output = getOutput(outQueue)

问题是队列仍然是空的,好像没有输出一样。只有当我将程序需要执行和终止的所有输入写入标准输入时,我才会得到输出(这不是我想要的)。例如,如果我这样做:

p.stdin.write("1\n5\n")
errors = getOutput(errQueue)
output = getOutput(outQueue)

有没有办法做我想做的事?


脚本将在 Linux 机器上运行。我更改了脚本并删除了 universal_newlines=True + 将 bufsize 设置为 1 并在写入后立即刷新标准输入。我仍然没有得到任何输出。

第二次尝试:

我尝试了这个解决方案,它对我有用:

from subprocess import Popen, PIPE

fw = open("tmpout", "wb")
fr = open("tmpout", "r")
p = Popen("./a.out", stdin = PIPE, stdout = fw, stderr = fw, bufsize = 1)
p.stdin.write("1\n")
out = fr.read()
p.stdin.write("5\n")
out = fr.read()
fw.close()
fr.close()

最佳答案

当前的答案都不适合我。最后,我得到了这个工作:

import subprocess


def start(executable_file):
return subprocess.Popen(
executable_file,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)


def read(process):
return process.stdout.readline().decode("utf-8").strip()


def write(process, message):
process.stdin.write(f"{message.strip()}\n".encode("utf-8"))
process.stdin.flush()


def terminate(process):
process.stdin.close()
process.terminate()
process.wait(timeout=0.2)


process = start("./dummy.py")
write(process, "hello dummy")
print(read(process))
terminate(process)

用这个 dummy.py 脚本测试:

#!/usr/bin/env python3.6

import random
import time

while True:
message = input()
time.sleep(random.uniform(0.1, 1.0)) # simulates process time
print(message[::-1])

注意事项(全部在函数中管理):

  • 输入/输出总是换行。
  • 每次写入后刷新 child 的标准输入。
  • 使用 child 的标准输出中的 readline()

在我看来这是一个非常简单的解决方案(不是我的,我在这里找到它:https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/)。我使用的是 Python 3.6。

关于python - 使用 Python 进行交互式输入/输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19880190/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com