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())
使用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())