2012-12-27 113 views
4

我有以下功能,它已经运行了好几个月。我没有更新我的Python版本(除非它发生在幕后?)。为什么python不再等待os.system完成?

def Blast(type, protein_sequence, start, end, genomic_sequence): 
    result = [] 
    M = re.search('M', protein_sequence) 
    if M: 
     query = protein_sequence[M.start():] 
     temp = open("temp.ORF", "w") 
     print >>temp, '>blasting' 
     print >>temp, query 
     temp.close() 
     cline = blastp(query="'temp.ORF'", db="DB.blast.txt", 
         evalue=0.01, outfmt=5, out=type + ".BLAST") 
     os.system(str(cline)) 
     blast_out = open(type + ".BLAST") 
     string = str(blast_out.read()) 
     DEF = re.search("<Hit_def>((E|L)\d)</Hit_def>", string) 

我收到blast_out=open(type+".BLAST")找不到指定文件的错误。该文件被创建为os.system调用所调用的程序输出的一部分。这通常需要大约30秒左右才能完成。但是,当我尝试运行该程序时,它会立即发出上面提到的错误。

我以为os.system()应该等待完成?
我应该以某种方式强制等待吗? (我不想硬编码等待时间)。

编辑: 我已经在命令行版本的BLAST程序中运行了cline输出。一切似乎都很好。

+0

尝试在'system'和'open'之间加入60秒的等待时间。如果问题仍然存在,那么外部程序以某种方式失败 –

+0

您也可以从os.system调用中打印出返回值,这应指示程序是否失败。通常是:0 =确定; > 0 = not OK –

+2

此外,请考虑使用['subprocess'](http://docs.python.org/2/library/subprocess.html) - 它具有更好的处理系统调用产生的错误的能力,并且通常应该用[代替'os.system'](http://docs.python.org/2/library/subprocess.html#replacing-os-system)。 –

回答

6

os.system确实在等待。但是在它所调用的程序中可能存在错误,所以文件不会被创建。在继续之前,您应该检查被调用程序的返回值。在一般情况下,程序应该返回0,当他们完成正常,另一个值时出现错误:

if os.system(str(cline)): 
    raise RuntimeError('program {} failed!'.format(str(cline))) 
blast_out=open(type+".BLAST") 

而不是抛出一个异常,你也可以从Blast函数返回,或尝试处理它用另一种方式。

更新:所谓的程序从命令行运行良好只告诉你,程序本身没有错。出现问题时,blast程序是否会返回有用的错误或消息?如果是这样,请考虑使用subprocess.Popen()代替os.system,并捕获标准输出,以及:

prog = subprocess.Popen(cline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = prog.communicate() 
# Now you can use `prog.returncode`, and inspect the `out` and `err` 
# strings to check for things that went wrong. 
+0

我不会在那里使用'ValueError'。 –

+0

你说得对。我将它改为'RuntimeError'。 –

+0

感谢您的建议。我没有失败。我尝试从命令行运行BLAST程序,程序运行良好... – Stylize

3

你也可以取代电话与subprocess.check_call到使用os.system,如果命令失败,将引发异常:

import subprocess as subp 
subp.check_call(str(cline), shell=True)