2012-07-04 47 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