问题描述
我有一个
app
,它从stdin
中读取内容,并在换行符之后返回结果为stdout
一个简单的(愚蠢的)示例:
$ app
Expand[(x+1)^2]<CR>
x^2 + 2*x + 1
100 - 4<CR>
96
打开和关闭“ 0”需要大量的初始化和清理工作(它是计算机代数系统的接口),因此我希望将其保持在最低水平。
我想在Python中打开此过程的管道,将字符串写入stdin
,并从stdout
读出结果。 Popen.communicate()
对此不起作用,因为它关闭了文件句柄,需要重新打开管道。
我已经尝试了一些与此相关问题类似的方法:
在不中断管道的情况下与一个进程多次通信?但我不确定如何等待输出。很难先验地知道the0要完成多长时间才能处理完手头的输入,因此我不想作任何假设。我想我的大部分困惑都来自这个问题:在子进程中进行非阻塞读取。Python中的PIPE指出混合高级功能和低级功能不是一个好主意。
编辑:
抱歉,我之前没有提供任何代码,被打断了。到目前为止,这是我已经尝试过的方法,并且似乎可以正常工作,我只是担心某些错误会被忽略:
from subprocess import Popen,PIPE
pipe = Popen([\"MathPipe\"],stdin=PIPE,stdout=PIPE)
expressions = [\"Expand[(x+1)^2]\",\"Integrate[Sin[x],{x,2*Pi}]\"] # ...
for expr in expressions:
pipe.stdin.write(expr)
while True:
line = pipe.stdout.readline()
if line != \'\':
print line
# output of MathPipe is always terminated by \';\'
if \";\" in line:
break
潜在的问题呢?
解决方法
使用子流程,您将无法可靠地执行此操作。您可能想看看使用pexpect库。在Windows上将无法使用-如果您在Windows上,请尝试使用winpexpect。
另外,如果您尝试使用Python进行数学运算,请查看SAGE。他们在与其他开源数学软件进行接口方面做了很多工作,因此他们很有可能已经完成了您要尝试的工作。
, 也许您可以将
stdin=subprocess.PIPE
作为参数传递给subprocess.Popen
。这将使该进程的stdin可作为通用的类似文件的对象使用:
import sys,subprocess
proc = subprocess.Popen([\"mathematica <args>\"],stdin=subprocess.PIPE,stdout=sys.stdout,shell=True)
proc.stdin.write(\"Expand[ (x-1)^2 ]\") # Write whatever to the process
proc.stdin.flush() # Ensure nothing is left in the buffer
proc.terminate() # Kill the process
这会将子进程的输出直接定向到python进程的stdout。如果您需要读取输出并首先进行一些编辑,那也是可以的。查看http://docs.python.org/library/subprocess.html#popen-objects。