如何在两个Python脚本之间通信?

2 投票
3 回答
10527 浏览
提问于 2025-04-16 18:13

我有一个第三方的Python脚本,它需要从命令行接收输入。这个脚本(input.py)里相关的代码大概是这样的:

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

如果第一个脚本只需要一个输入,我可以通过去掉第二个写入的调用来让第二个脚本正常工作。如果第一个脚本需要多个输入,那么我就会遇到上面的错误。

3 个回答

2

你可以看看 Pexpect

Pexpect 是一个纯 Python 模块,用来启动子应用程序、控制它们,并对它们输出的预期内容做出反应。这个子应用程序可以是任何可执行文件(比如在你的情况下,另一个 Python 脚本)。它的工作方式类似于 Unix 工具 "expect"。

4

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

这种方法是过去选择少时的产物。Pexpect,虽然它有其优点,但实际上只是让一个糟糕的接口看起来好一些。像这样的命令行控制通常依赖于时间,这样会很快变得麻烦且容易出错。只有在没有其他选择时才使用它。

Python提供了许多更强大的脚本方法。除非你无法访问脚本内部(在Python中,你几乎总是可以),否则你应该写一个harness.py脚本,把第三方脚本作为库导入,并通过直接调用它的方法/函数来进行控制。

虽然你现在的情况可能不允许这样做,但在Python脚本中,命令行通信应该是最后的选择,而不是第一选择。

6

试试这个:

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

撰写回答