📅  最后修改于: 2023-12-03 15:05:37.253000             🧑  作者: Mango
tqdm
是一个Python进度条库,它可以轻松地为代码创建进度条,以提供用户友好的提示和可视化,以及代码的估计剩余时间和完成进度。然而,当程序中断并重新启动时,如何在进度条上继续,以避免从头开始?
position
参数在创建tqdm
实例时,可以使用position
参数指定进度条的位置。该参数可以是整数值,表示该进程的唯一标识符。这使得您可以在同一位置重新启动单个进度条,而不会打乱整个输出。
from tqdm import tqdm
import time
# 创建进度条实例并指定位置为0
pbar = tqdm(total=100, position=0)
# 循环迭代,并在每次迭代时更新进度条
for i in range(100):
# 模拟一些计算任务
time.sleep(0.1)
pbar.update(1)
# 中断程序,重新启动后仍然需要继续。
# 可以使用相同的位置来继续进度条。
# 注意:此时不应先设置total
pbar = tqdm(total=100, position=0)
# 减少迭代次数,以显示继续
for i in range(50):
# 模拟一些计算任务
time.sleep(0.1)
pbar.update(1)
# 关闭进度条
pbar.close()
initial
参数在某些情况下,您可能不希望指定进度条的位置,或者可能已经将tqdm
实例作为参数传递给其他函数。在这种情况下,可以使用initial
参数来设置进度条的起始值,在重新启动程序后,进度条将从指定的位置开始而不是从零开始。
from tqdm import tqdm
import time
# 创建进度条实例并使用初始值
pbar = tqdm(total=100, initial=50)
# 迭代计算以更新进度条
for i in range(50, 100):
# 模拟一些计算任务
time.sleep(0.1)
# 更新进度条
pbar.update(1)
# 中断程序,重新启动后继续从50开始。
pbar = tqdm(total=100, initial=50)
# 在这里增加一些迭代次数以确定进度条是否继续。
for i in range(20):
# 模拟一些计算任务
time.sleep(0.1)
# 更新进度条
pbar.update(1)
# 关闭进度条
pbar.close()
在某些情况下,如果您的程序中断了,并且您无法指定进度条的位置或初始值,您可以使用Python的pickle序列化机制保存tqdm
实例的当前状态,这样您可以在重启程序时恢复进度,并无需手动调整进度条位置或初始值。
import pickle
from tqdm import tqdm
import time
class Wrapper:
'''
仿造tqdm封装类,实现pickle序列化和重写__enter__和__exit__方法来保证实例的正确启动和关闭
'''
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.pbar = None
self.file = None
def __enter__(self):
self.file = open(self.kwargs.get('filename', 'progress.pkl'), 'wb')
return self
def __exit__(self, *exc):
self.pbar.close()
pickle.dump(self.kwargs, self.file)
self.file.close()
def start(self):
if self.file is not None and os.path.exists(self.file.name):
self.file = open(self.file.name, 'rb')
kwargs = pickle.load(self.file)
initial = kwargs.get('initial', 0)
total = kwargs.get('total', None)
desc = kwargs.get('desc', '')
unit = kwargs.get('unit', 'it')
unit_scale = kwargs.get('unit_scale', False)
position = kwargs.get('position', None)
dynamic_ncols = kwargs.get('dynamic ncols', False)
leave = kwargs.get('leave', False)
bar_format = kwargs.get('bar_format', None)
initial = self.pbar.n if position is None else position
self.pbar = tqdm(initial=initial, total=total, desc=desc, unit=unit, unit_scale=unit_scale, position=position, dynamic_ncols=dynamic_ncols, leave=leave,bar_format=bar_format, **self.kwargs)
else:
self.pbar = tqdm(*self.args, **self.kwargs)
def update(self, n=1):
self.pbar.update(n)
# 在上下文管理器中使用包装器,这样实例将在退出上下文时自动保存并关闭。
with Wrapper(total=100, desc='Task Description', filename='progress.pkl') as wrapper:
# 在开始进度条实例前加入重启检查
wrapper.start()
for i in range(wrapper.pbar.n, 100):
# 模拟一些计算任务
time.sleep(0.1)
# 更新进度条
wrapper.update(1)
在这篇文章中,我们介绍了 tqdm
库中间如何中断和继续。在 Pandas 实现数据预处理和数据分析的时候,可以使用 tqdm
记录中间执行情况,避免程序在繁重的计算任务中陷入死循环而造成挂起,初学者可以通过本文来深入了解 tqdm
库的用法。