0

我正在编写一个需要调用外部程序 hmm3align 的 Python 程序,该程序从命令行操作如下:

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)

所以我不能通过标准输入将两个单独的变量传递给程序。我应该提到,当一个类似的外部程序只需要一个输入文件时,我已经能够使子进程在该程序上工作。

我该如何进行这项工作?是否可以使用具有多个输入的子流程?我查看了文档并没有看到这个问题得到回答。提前致谢。

4

1 回答 1

1

标准输入是单个数据流;在 Unix 上,它是一个连接到单向管道输出端的文件描述符。按照惯例,从命令行上指定的单个文件读取的程序将被理解为从标准输入读取而不是从文件读取的指令。但是,对于从两个文件读取的程序,没有办法从 stdin 读取两次,因为它是单个数据流。-

还有其他可用于通信的文件描述符(stdin 是 fd 0,stdout 是 fd 1,stderr 是 fd 2)但是没有传统的方法来指定它们而不是文件。

最有可能在这里工作的解决方案是命名管道(FIFO);在 Python 中,用于os.mkfifo创建命名管道并将os.unlink其删除。然后,您可以在写入程序(使用 )时将其名称传递给程序(它将显示为可以读取的文件open)。

于 2012-06-21T16:59:15.027 回答