2011-03-22 48 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

相关问题