【问题标题】:Python subprocess with two inputs具有两个输入的 Python 子进程
【发布时间】: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


【解决方案1】:

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-05-02
  • 2015-08-05
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 2012-05-13
  • 2011-04-12
相关资源
最近更新 更多