子流程无法捕获标准输出

时间:2010-05-18 11:21:35

标签: python subprocess biopython

我正在尝试使用fasta文件输入生成树,并使用MuscleCommandline

进行对齐
import sys,os, subprocess
from Bio import AlignIO
from Bio.Align.Applications import MuscleCommandline
cline = MuscleCommandline(input="c:\Python26\opuntia.fasta")
child= subprocess.Popen(str(cline),
                         stdout = subprocess.PIPE,
                         stderr=subprocess.PIPE,
                        shell=(sys.platform!="win32"))
align=AlignIO.read(child.stdout,"fasta")
outfile=open('c:\Python26\opuntia.phy','w')
AlignIO.write([align],outfile,'phylip')
outfile.close()

我总是遇到这些问题

Traceback (most recent call last):
  File "<string>", line 244, in run_nodebug
  File "C:\Python26\muscleIO.py", line 11, in <module>
    align=AlignIO.read(child.stdout,"fasta")
  File "C:\Python26\Lib\site-packages\Bio\AlignIO\__init__.py", line 423, in read
    raise ValueError("No records found in handle")
ValueError: No records found in handle

4 个答案:

答案 0 :(得分:4)

这里有一些问题:

  1. 在子进程调用之后需要一个child.wait(),这样你的代码就会等到外部程序运行完毕。

  2. 肌肉实际上并没有写入stdout,即使帮助文档说它确实如此,至少我在这里有v3.6。我相信最新的是v3.8所以这可能是固定的。

  3. Biopython告诉你,你传递它的标准输出是空的,这是你看到的错误。尝试直接运行命令行:

    muscle -in opuntia.fasta

    看看你是否看到FASTA输出。这是一个修复等待问题并使用中间输出文件的版本:

    
    import sys,os, subprocess
    from Bio import AlignIO
    from Bio.Align.Applications import MuscleCommandline
    out_file = "opuntia.aln"
    cline = MuscleCommandline(input="opuntia.fasta", out=out_file)
    child= subprocess.Popen(str(cline),
                             stdout = subprocess.PIPE,
                             stderr=subprocess.PIPE,
                            shell=(sys.platform!="win32"))
    child.wait()
    with open(out_file) as align_handle:
        align=AlignIO.read(align_handle,"fasta")
    outfile=open('opuntia.phy','w')
    AlignIO.write([align],outfile,'phylip')
    outfile.close()
    os.remove(out_file)
    

答案 1 :(得分:2)

来自subproccess library的文档:

  

警告

     

使用communic()而不是   .stdin.write,.stdout.read或   .stderr.read以避免由于的死锁   任何其他OS管道缓冲区   填补和阻止孩子   过程

所以也许你可以尝试类似的东西:

mydata = child.communicate()[0]

答案 2 :(得分:1)

您的输出文件名中有一个不受保护的反斜杠,这绝不是好事。

使用'r'获取原始字符串,即r'c:\Python26\opuntia.phy'

答案 3 :(得分:0)

Biopython 1.54今天发布了Bio.Phylo模块的稳定版本。我用一个用于生成树的示例管道更新了文档。为简单起见,该示例使用ClustalW来对齐序列并生成树,而不是Muscle和Phylip,但大多数代码仍然相同或类似。

http://biopython.org/wiki/Phylo#Example_pipeline

如果您已经使用Phylip生成了一个树(使用.phy对齐作为输入),您仍然可以按照Phylo示例进行操作。 Phylip创建一个名为“outttree”或“foo.tree”的Newick文件。

(请随意将此与Brad的答案合并;我还不能在该帖中写评论。)