当我的脚本正在执行一些可能需要时间的任务时,我如何使用进度条?

例如,一个函数需要一段时间才能完成,完成后返回True。如何在函数执行期间显示进度条?

请注意,我需要这是实时的,所以我不知道该怎么做。我需要一根线吗?我不知道。

现在我没有打印任何东西,而函数正在执行,但一个进度条会很好。此外,我更感兴趣的是从代码的角度如何做到这一点。


当前回答

使用这个库:fish (GitHub)。

用法:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

玩得开心!

其他回答

使用tqdm (conda install tqdm或pip install tqdm),你可以在一秒钟内为你的循环添加一个进度计:

from time import sleep
from tqdm import tqdm
for i in tqdm(range(10)):
    sleep(3)

 60%|██████    | 6/10 [00:18<00:12,  0.33 it/s]

此外,还有一个笔记本版本:

from tqdm.notebook import tqdm
for i in tqdm(range(100)):
    sleep(3)

您可以使用tqdm。Auto代替tqdm。笔记本电脑工作在两个终端和笔记本电脑。

tqdm。Contrib包含一些辅助函数,用于执行枚举、映射和压缩等操作。在tqdm.contrib.concurrent中有并发映射。

你甚至可以使用tqdm.contrib.telegram或tqdm.contrib.discord从jupyter笔记本断开连接后将进度发送到你的手机。

在这里寻找等效的解决方案后,我只是为我的需求做了一个简单的进度类。我想我应该把它贴出来。

from __future__ import print_function
import sys
import re


class ProgressBar(object):
    DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
    FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'

    def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                 output=sys.stderr):
        assert len(symbol) == 1

        self.total = total
        self.width = width
        self.symbol = symbol
        self.output = output
        self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
            r'\g<name>%dd' % len(str(total)), fmt)

        self.current = 0

    def __call__(self):
        percent = self.current / float(self.total)
        size = int(self.width * percent)
        remaining = self.total - self.current
        bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'

        args = {
            'total': self.total,
            'bar': bar,
            'current': self.current,
            'percent': percent * 100,
            'remaining': remaining
        }
        print('\r' + self.fmt % args, file=self.output, end='')

    def done(self):
        self.current = self.total
        self()
        print('', file=self.output)

例子:

from time import sleep

progress = ProgressBar(80, fmt=ProgressBar.FULL)

for x in xrange(progress.total):
    progress.current += 1
    progress()
    sleep(0.1)
progress.done()

将打印以下内容:

[========] 17/80 (21%) 63

如果你的工作不能被分解成可测量的块,你可以在一个新的线程中调用你的函数,并记录它所花费的时间:

import thread
import time
import sys

def work():
    time.sleep( 5 )

def locked_call( func, lock ):
    lock.acquire()
    func()
    lock.release()

lock = thread.allocate_lock()
thread.start_new_thread( locked_call, ( work, lock, ) )

# This part is icky...
while( not lock.locked() ):
    time.sleep( 0.1 )

while( lock.locked() ):
    sys.stdout.write( "*" )
    sys.stdout.flush()
    time.sleep( 1 )
print "\nWork Done"

显然,您可以根据需要提高计时精度。

使用这个库:fish (GitHub)。

用法:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

玩得开心!

当在jupyter笔记本上运行时,使用普通的tqdm无法工作,因为它将输出写在多行上。用这个代替:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)