2012-01-31 33 views
0

這是windows環境下的python程序的一部分。我試圖做到以下幾點:從HTML ,我想創建一個PDF格式,然後打開它:檢查shell下的進程停止

 
    #create the pdf 
    os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name)) 
    #open the current pdf 
    os.system("start %s%s" %(output_directory, pdf_document_name)) 

的問題是創建PDF比較慢,所以我得到一個錯誤的,有時劇本從終端說,沒有這樣的名字的文件。
我想問一下,只有當創建成功並完成時,才能打開pdf。我知道如何通過調用time.sleep()來實現,但我認爲這不是太專業。
非常感謝,
D

回答

2

無論您用於執行shell命令(子進程,os.system等)的方法如何,您都應該在嘗試打開它之前驗證您的文件是否存在。然後,您可以在嘗試打開文件之前將延遲放入File-Exists-Else-Wait-Repeat循環中。 可以使用os.path.exists()做到這一點:

#create the pdf 
os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name)) 

#loop until pdf exists, but add some timer to avoid endless repetition 
maxiterations = 60 
exists = False 
for i in range(maxiterations): 
    if os.path.exists(os.path.join(output_directory, pdf_document_name)): 
     exists = True 
     break; 
    time.sleep(1) 
#open the current pdf 
if exists: 
    os.system("start %s%s" %(output_directory, pdf_document_name)) 
else: 
    print 'Could not find file %s to open' % os.path.join(output_directory, pdf_document_name) 

要看的另一件事是,這引入了一個安全漏洞,因爲該文件可能在您之間傳遞的時間驗證它,打開它(例如,它可能會改變已被惡意代碼所取代)。 解決這個問題的另一種方法是嘗試在try ... except ...塊內打開它,但這並不能真正解決安全問題(該文件可能在創建和嘗試打開它之後被替換)。

+0

非常感謝Nisan.H,它工作。 – dola 2012-02-03 14:21:55

1

我不認爲有什麼「不專業」使用time.sleep()。實際上,對於您建議的解決方案而言,最不專業(或最少Pythonic)的東西是使用os.system。改用subprocess模塊的功能。在這種情況下,您可以使用subprocess.call,它在繼續之前等待程序退出。因此,例如,如果你在交互式解釋這樣做:

import subprocess, shlex 
subprocess.call(shlex.split('sleep 5')) 

你會看到,Python的等待五秒鐘sleep繼續之前完成。 (然後它返回退出代碼。)Shlex僅將命令行分割成供call使用的參數列表或subprocess提供的其他幾個函數和類。

>>> shlex.split("start wkhtmltopdf.exe result.html %s%s" %('out_dir/', 'pdf_name')) 
['start', 'wkhtmltopdf.exe', 'result.html', 'out_dir/pdf_name']