2012-12-27 85 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)