2011-03-22 20 views
2

我正在嘗試做一個進度條。是否有可能每解析x行就調用一個函數?

是否可以計算腳本上的執行行數並將每個執行行與函數關聯起來,以便每行或每5行都執行一次?

我的計劃是每次執行一行時更新進度欄。

可能嗎?我可以使用裝飾器來做到這一點嗎?

+0

所以,恩,你喜歡這兩個答案嗎? – 2011-03-27 00:23:07

回答

1

您是否可以從Observer對象中受益?

class Observer(object): 
def __init__(self): 
    self._subjects = [] 
def add_subject(self, subject): 
    self._subjects.append(subject) 
def notify(self, percentage): 
    for subject in self._subjects: 
    subject.notify(percentage) 

class Subject(object): 
    def notify(self, percentage): 
    # in this example, I assume that you have a class 
    # that understand what does "update_progress_bar(%)" means 
    # and it is inheriting from `Subject` 
    self.update_progress_bar(percentage) 

s = Subject() 
o = Observer() 
o.add_subject(s) 
# your code 

def my_fun(): 
blah() 
blah2() 
o.notify(20) 
blah3() 
o.notify(30) 
blah4() 
o.notify(100) 

所以,你創建一個Observer類,其唯一目的是跟蹤運行的。您可以創建一個或幾個Subject對象,可以通過通知Observer:在這種情況下他們得到通知完成百分比。當每個Subject得到通知時,他們可以做任何他們想做的事情,比如更新進度條。

9

是的,你可以通過讓Python在每次處理一條線時提醒你。下面是打印每updatelines次執行一條線後到標準輸出的例子:

import sys 

class EveryNLines(object): 
    def __init__(self, updatelines): 
     self.processed = 0 
     self.updatelines = updatelines 

    def __call__(self, frame, event, arg): 
     if event == 'line': 
      self.processed += 1 
      if not self.processed % self.updatelines: 
       print 'do something' 
     return self 

def testloop(): 
    for i in range(5): 
     print i 

oldtracer = sys.gettrace() 
sys.settrace(EveryNLines(3)) 
testloop() 
sys.settrace(oldtracer) 

你當然可以把它轉換成用於方便的裝飾。

+1

這絕對是做OP所要求的正確方法,但由於執行過程中發出的跟蹤事件的數量,它會帶來很多開銷。遠遠好於將實際操作放到工作者線程或進程,並定期更新主線程,然後更新進度條。 – ncoghlan 2011-03-23 02:13:54

+1

哦,當然,這就是我在自己的應用程序中所做的:讀取MB,更新欄。讀另一個MB,再次更新欄。我只是認爲這是一個非常酷的技巧,即使你不想一直使用它,也可以使原始請求成爲可能。 – 2011-03-23 05:00:37

相關問題