使用Python标准库显示功能状态

时间:2015-02-02 21:46:37

标签: python python-2.7

我正在调用一个功能(无法修改)来分析数据,可能需要几分钟到几小时才能完成。我正在尝试定期打印状态/进度,让用户知道分析仍在进行中。

自:

  1. 我不知道分析需要多长时间才能完成和
  2. 我只能使用Python的标准库
  3. 然后使用进度条包不会起作用。我能够使用多处理来实现这一目标:

    import multiprocessing.pool import ThreadPool
    import time
    
    def analysis():
        #Perform analysis that takes a long time and cannot be modified
    
    pool = ThreadPool(processes=2)
    t = pool.apply_async(func = analysis)
    start_time = time.time()
    while not t.ready():
        print "Analyzing..."
        time.sleep(2)
    

    如果我可以避免使用多进程并且它可以像linux一样就地更新,那将是很好的" watch"命令。

1 个答案:

答案 0 :(得分:3)

不完全确定你在问什么。如果您希望“静态分析”消息就地更新而不是一行一行地添加到输出中,您可以尝试这样的事情:

spinner = itertools.cycle("|/~\\")
while not t.ready():
    sys.stdout.write("\r%s: still analyzing %s" % (time.ctime(), next(spinner)))
    sys.stdout.flush()
    time.sleep(.5)

这里,\r字符(回车)用于将输出位置重置为行的开头。这将定期使用当前时间和“微调器”动画更新该行。

在Python 3中,您可以使用print函数的参数执行相同的操作。对于更复杂的输出,您可以考虑使用curses。有关小例子,请参阅this


如果你想为多个函数或多次调用同一个函数执行此操作,你也可以将它作为装饰器。然后每次调用时都会以这种方式执行该函数。这仍然使用进程,但现在它们对用户是隐藏的。

def monitor(f):
    def f_():
        pool = ThreadPool(processes=2)
        t = pool.apply_async(func=f)
        spinner = itertools.cycle("|/~\\")
        while not t.ready():
            sys.stdout.write("\r%s: running %s %s" % (time.ctime(), f.__name__, next(spinner)))
            sys.stdout.flush()
            time.sleep(.5)
        sys.stdout.write("\n")
    return f_

@monitor
def analysis():
    time.sleep(4)

analysis()

当然,这是一个非常简单的版本,既不支持参数也不支持返回值。说实话,到目前为止我还没有使用Python中的线程,我不想表现出任何错误。