2012-07-04 108 views
4

我正在做一個進度指示器對於一些長時間運行控制檯程序意圖使用這樣的:這是一個上下文管理器的有效用例嗎?

pi = ProgressIndicator() 
for x in somelongstuff: 
    do stuff 
    pi.update() 
pi.print_totals() 

基本上,它應該輸出某種與點和線的進度條,以及類似結尾處理「234234個字節」。

我認爲這將是很好的把它作爲一個上下文管理器:

with ProgressIndicator() as pi: 
    for x in somelongstuff: 
     do stuff 
     pi.update() 

但是有一些關心我,這個解決方案的幾件事情:

  • 的縮進使得指示器功能似乎比實際上更重要
  • 我不希望ProgressIndicator處理循環中可能發生的任何異常

這是一個上下文管理器的有效用例嗎?你可以建議什麼其他解決方案?

回答

3

這絕對是一個有效的用例。上下文管理器不需要處理異常,如果你不想要的話,儘管你想要結束輸出進度條的行,以防止它與追蹤混淆,並且不打印總計如果通過例外退出。

關於縮進,我認爲讓用戶看到進度實際上是一個非常重要的特性,所以它可以佔用縮進級別。

2

有其中有一個非常類似的API ProgressTask,您可以使用這樣的GUI應用程序:

def slow_func(): 
    t = nuke.ProgressTask() 
    t.setMessage("Doing something") 
    for x in range(100): 
     do_something() 
     t.setProgress(x+1) 

ProgressTask.__del__被調用時,進度條消失的UI。這很好地工作在大多數情況下,但是,如果將引發異常(例如,通過do_something()),追溯對象保持到ProgressTask對象的引用,所以進度條卡住(直到另一個回溯發生)

ProgressTask實現了上下文管理器協議,它可以使用__exit__方法來確保進度條已被隱藏。

對於命令行用戶界面(這聽起來像是你正在編寫的),這可能不是問題,但你可以執行類似的清理任務,例如顯示######### 100% (error)類型欄,並確保回溯輸出不是'牛逼搞砸等

沒有理由你的進度條類不能以這兩種方式可用 - 大多數情況下,管理者是完全可以作爲包括經常對象和上下文管理,如:

lock = threading.Lock() 
lock.acquire() 
lock.release() 
# or: 
with lock: 
    pass