2011-05-23 122 views
2

我有一个3d方python脚本,它从命令行接受输入。从这个脚本(input.py)相关的代码如下所示:如何在两个python脚本之间进行通信?

import sys 

def chooseinput(): 
    valid_inputs = ('a', 'b') 
    inp = raw_input('Enter choice (%s): ' % "/".join(valid_inputs)) 
    if inp not in valid_inputs: 
     sys.stderr.write("Unsupported input %s\n" % inp) 
     return 
    print 'You chose ' + '\'' + inp + '\'' 
    return inp 

if __name__ == "__main__": 
    chooseinput() 
    # do something with the input... 
    chooseinput() 
    # do something with the input... 

我想写另一个python脚本(harness.py)来生成以上脚本的输入。

import subprocess 

def harness(): 
    p = subprocess.Popen(['python', 'input.py'], stdin=subprocess.PIPE) 
    p.stdin.write('a') 
    p.stdin.write('b') 

if __name__ == '__main__': 
    harness() 

在命令行中,我跑:

$ python harness.py 
Enter choice (a/b): Enter choice (a/b): Traceback (most recent call last): 
    File "input.py", line 13, in <module> 
    chooseinput() 
    File "input.py", line 5, in chooseinput 
    inp = raw_input('Enter choice (%s): ' % "/".join(valid_inputs)) 
EOFError: EOF when reading a line 

如果我只在第一个脚本一个输入,然后我就可以通过移除第二写入调用使第二个脚本工作。如果第一个脚本需要多个输入,那么我会得到上述错误。

回答

6

尝试:

p.stdin.write('a\n') 
p.stdin.write('b\n') 
2

你应该看看Pexpect

Pexpect是一个用于产生子应用程序的纯Python模块;控制他们;并对其产出中的预期模式做出反应。子应用程序可以是任何可执行文件(例如,如您的情况,另一个python脚本)。它的工作方式类似于unix工具“expect”。

+0

谢谢,这看起来非常方便。 – Ravi 2011-05-24 00:15:04

3

linuts答案在你的简单例子中效果很好,但为了未来读者的利益,我强烈建议不要使用这种方法在Python脚本之间进行通信。

这种方法是一个倒退到少数其他选项可用时。 Pexpect,祝福它的心脏,可能确实是一个很好的计划,但它只是一个愉快的面对一个悲惨的接口技术。像这样的命令行控制通常是依赖于时序的,这使得它很快乏味并且容易出错。只有当你没有其他选择时才使用它。

Python为脚本编写带来了许多更强大的方法。除非您无法访问脚本内部(使用Python,您几乎总是这样做),否则应该编写harness.py脚本将三方脚本作为库导入,并通过直接调用其方法/函数以编程方式控制它。

您目前的困境可能不允许,但对于Python脚本,命令行通信应该是最后一个选择,而不是第一个。

+0

@JS非常好,如果你有一个python模块,你想要利用你的第一选择的功能应该是导入该模块。 python的一个重要特性是导入和利用另一个python模块的类/对象/函数是多么简单 - 即使模块没有考虑到这个功能。命令行通信应该是最后的手段。 – 2011-05-24 17:39:38

相关问题