鱼C论坛

 找回密码
 立即注册
查看: 2249|回复: 9

关于Subprocess stdin ,stdout的多次输入,输出。

[复制链接]
发表于 2023-11-24 15:25:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
有一个猜数程序:
import random

num = random.randint(1, 100)
count = 0
while True:
    ans = int(input("Please input a number between 1 and 100:"))
    count += 1
    if ans == num:
        print(f"The number is {ans}!")
        break
    elif ans > num:
        print("Too Large!")
        continue
    else:
        print("Too Small!")
        continue
现在使用subprocess模块,运行该程序进行自动猜数。
import subprocess
import shlex

process = subprocess.Popen(shlex.split('python ask.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
process.stdin.write(b"50")
process.stdin.close()
print(process.stdout.read().decode())
如何才能多次进行猜想,并输出结果呢?,使用stdin.write()和stdout.read(),好像只能进行一次输出输出过程。在没有进行stdin.close(),没法进行stdout.read(),就没法多次输出猜想过程。

我在网上找的了stdout.read1()方法可以输出当前stdout结果,写出下面程序可以自动猜想,但是stdout.read1()好像不是subprocess的方法,在Pycharm里面会有黄色警告。
import subprocess
import shlex

low = 1
high = 100
mid = (low + high) // 2
process = subprocess.Popen(shlex.split('python ask.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
print(process.stdout.read1().decode())
process.stdin.write(f'{mid}\n'.encode())
print(f"{mid}")
process.stdin.flush()
while True:
    hint = process.stdout.read1().decode()
    print(hint)
    if "Too Small" in hint:
        low = mid + 1
        mid = (low + high) // 2
    elif "Too Large" in hint:
        high = mid - 1
        mid = (low + high) // 2
    else:
        print(process.stdout.read1().decode())
        break

    process.stdin.write(f'{mid}\n'.encode())

    print(process.stdout.read1().decode())
    process.stdin.flush()
    print(f"{mid}")
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-24 15:25:59 | 显示全部楼层
问题的关键在于`process.stdout.read()`是一个阻塞的操作,只有当子进程的输出缓冲区中有数据时才会返回。所以在你的代码中,第一次读取输出后,如果没有再次写入数据,程序会一直阻塞在读取stdout的操作,导致后续的猜数和输出无法进行。

解决这个问题的方法是使用`process.stdout.readline()`来逐行读取输出,而不是一次性读取所有的输出。这样可以确保在每次写入数据后,都能够及时读取并处理相应的输出。

以下是修改后的示例代码:
  1. import subprocess
  2. import shlex
  3. low = 1
  4. high = 100
  5. mid = (low + high) // 2
  6. process = subprocess.Popen(shlex.split('python ask.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  7. while True:
  8.     print(process.stdout.readline().decode())
  9.     process.stdin.write(f'{mid}\n'.encode())
  10.     process.stdin.flush()
  11.     hint = process.stdout.readline().decode()
  12.     print(hint)
  13.     if "Too Small" in hint:
  14.         low = mid + 1
  15.         mid = (low + high) // 2
  16.     elif "Too Large" in hint:
  17.         high = mid - 1
  18.         mid = (low + high) // 2
  19.     else:
  20.         print(process.stdout.readline().decode())
  21.         break
  22.     print(process.stdout.readline().decode())
  23.     process.stdin.write(f'{mid}\n'.encode())
  24.     process.stdin.flush()
复制代码

通过使用`process.stdout.readline()`来逐行读取输出,可以保证在每次写入数据后都能及时读取输出,实现多次猜数和输出的过程。
以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-24 15:26:23 | 显示全部楼层

回帖奖励 +10 鱼币

在使用Python的subprocess模块进行多次输入和输出时,可以通过不断循环调用stdin.write()和stdout.readline()来实现。下面是一个例子:
  1. import subprocess
  2. import shlex
  3. process = subprocess.Popen(shlex.split('python ask.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  4. print(process.stdout.readline().decode())  # 读取第一行输出
  5. while True:
  6.     guess = int(input("Please input a number:"))
  7.     process.stdin.write(f"{guess}\n".encode())  # 将猜测的数字写入stdin
  8.     process.stdin.flush()  # 刷新stdin缓冲区
  9.     output = process.stdout.readline().decode()  # 读取输出结果
  10.     print(output)
  11.     if "The number is" in output:
  12.         break
  13. process.stdin.close()
  14. process.stdout.close()
  15. process.stderr.close()
复制代码

在这个例子中,我们首先读取了程序的初始输出,然后进入一个循环,不断从用户输入获取猜测的数字,并将其写入stdin,然后读取程序的输出结果。当程序输出包含"The number is"时,循环结束。

希望这个例子对你有所帮助。如果你还有其他问题,请随时提问。

回复来自于CHAT-GPT。回复仅供参考,如有人工回答,最佳答案请优先选择人工
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-24 15:41:00 | 显示全部楼层
Mike_python小 发表于 2023-11-24 15:26
在使用Python的subprocess模块进行多次输入和输出时,可以通过不断循环调用stdin.write()和stdout.readline ...

答案不对,没有输出结果,程序都不会停止
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-24 19:00:40 | 显示全部楼层

回帖奖励 +10 鱼币

6
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-24 21:13:47 | 显示全部楼层

回帖奖励 +10 鱼币

强烈建议问问GPT
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-11-24 21:14:18 | 显示全部楼层

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-24 21:33:00 | 显示全部楼层

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-25 09:54:58 | 显示全部楼层

回帖奖励 +10 鱼币

GPT!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-25 10:01:35 | 显示全部楼层
论坛有GPT
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-11 00:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表