【发布时间】:2012-06-23 22:06:34
【问题描述】:
我正在编写一个Python程序,需要调用一个外部程序hmm3align,从命令行操作如下:
hmm3align hmm_file fasta_file -o output_file
所以通常情况下,程序需要两个输入文件并将结果写入第三个文件。我的程序实际上有多个调用外部程序的情况,但这是外部程序有两个文件输入的唯一情况。我的意图是避免写入和读取文件以允许这些外部程序相互通信;我希望在会话期间将所有数据存储为 Python 变量,并在需要时将这些变量提供给外部程序。
在 Python 程序中需要调用 hmm3align 的地方,我已经有两个 Python 变量 hmm_model 和 fasta_model,它们分别包含通常分别包含在 hmm_file 和 fasta_file 中的信息。我想要做的是通过标准输入将 hmm_model 和 fasta_model 传递给 hmm3align(因为我认为这是将它们作为输入提供的唯一方法),然后将结果从标准输出捕获到名为 align_results 的第三个 Python 变量中。为此,我创建了一个使用 subprocess 模块的单独函数,如下所示:
def hmmalign(hmm_model,fasta):
args = ["/clusterfs/oha/software/bin/hmm3align",
"-", "-",
"-o", "/dev/stdout"]
process = subprocess.Popen(args, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return process.communicate(hmm_model,fasta)[0]
如您所见,我正在尝试通过标准输入发送这两个变量。 args 列表中的两个“-”用于捕获这两个变量;我在其他示例中看到了“-”,但它们的目的并不清楚,我可能会误解。
果然,我在 Traceback 的最后得到如下错误:
TypeError: communicate() takes at most 2 arguments (3 given)
所以我不能通过标准输入将两个单独的变量传递给程序。我应该提到,当一个类似的外部程序只需要一个输入文件时,我已经能够使子进程在该程序上工作。
我该如何进行这项工作?是否可以使用具有多个输入的子流程?我查看了文档并没有看到这个问题得到回答。提前致谢。
【问题讨论】:
-
如果外部程序设计为只读取文件,我不确定您可以做些什么。在命令行上传递数据将不起作用,因为外部程序会尝试将其用作文件路径。
-
您得到的错误来自 Communicate() 函数。这个函数只接受一个显式参数
communicate(input=None),它是一个要传递给执行子进程的文本字符串。在您的情况下,由于您已经将 stdin、stdout 和 stderr 绑定到 PIPE,因此您应该在不带参数process.communicate()的情况下调用它。不过,这不会对参数作为文件的问题做任何事情。见docs.python.org/library/subprocess.html
标签: python subprocess