Python 3 如何与外部程序交互?

How to interact with an external program in Python 3?

使用Python 3,我想执行一个外部程序,通过向标准输入提供一些文本与之交互,然后打印结果。

例如,我创建了以下外部程序,名为 test.py:

print('Test Program')
print('1 First option, 2 Second Option')

choice = input()

if choice == '1':
    second_param = input('Insert second param: ')
    result = choice + ' ' + second_param
        
    print(result)

如果我直接 运行 这个程序,它会按预期工作。如果我提供输入 1 然后 2,结果是 1 2.

我想在另一个脚本中 运行 这个程序并与其交互以打印相同的结果。

阅读 subprocess 的文档并查看关于 SO 的类似问题后,我得出以下结论:

EXTERNAL_PROG = 'test.py'

p = Popen(['py', EXTERNAL_PROG], stdout=PIPE, stdin=PIPE, shell=True)

print(p.stdout.readline().decode('utf-8'))
print(p.stdout.readline().decode('utf-8'))
p.stdin.write(b'1\n')
p.stdin.write(b'2\n')
print(p.stdout.readline().decode('utf-8'))

然而,当我 运行 代码时,程序在打印 1 First option, 2 Second Option 后冻结,我需要重新启动我的 shell。这可能是因为 subprocess.stdout.readline() 希望找到一个换行符,而第二个参数的提示不包含换行符。


我发现了 2 个关于类似内容的 SO 问题,但我无法让它发挥作用。

Here, the answer recommends using the pexpect 模块。我尝试根据我的情况调整代码,但没有成功。

Here,建议是用-u,但是加了也没啥变化。


我知道可以通过修改 test.py 找到解决方案,但在我的情况下这是不可能的,因为我需要使用另一个外部程序,这只是基于它的一个最小示例。

如果您的程序有固定的输入(意味着输入在 运行 时间没有改变)那么这个解决方案可能是相关的。

回答

首先创建文件。

  • 输入文件。将其命名为 input.txt 并在其中放入 1 2

command = "python test.py < input.txt > output.txt 2>&1"

# now run this command

os.system(command)

当你运行这个时,你会在同一目录中找到output.txt。如果您的程序成功执行,则 output.txt 包含代码 test.py 的输出,但如果您的代码出现任何错误,则错误在 output.txt.

随心所欲

main.py变成

import sys
from subprocess import PIPE, Popen

EXTERNAL_PROG = 'test.py'

p = Popen(['python3', EXTERNAL_PROG], stdout=PIPE, stdin=PIPE, stderr=PIPE)

print(p.stdout.readline())
print(p.stdout.readline())
p.stdin.write(b'1\n')
p.stdin.write(b'2\n')
p.stdin.flush()
print(p.stdout.readline())
print(p.stdout.readline())