我想添加一个进度条来显示执行函数的进度。该函数从 postgresql 数据集中导入数据,最后绘制每个分段百分比的 bar_chart。
这是我的代码:
class RfmTable:
def __init__(self,table_name,start_date,end_date):
self.table_name = table_name
self.start_date = start_date
self.end_date = end_date
self.quintiles = {}
def rfm_chart(self):
conn = psycopg2.connect(database=database_name, user=user_name,
password=password_info, host=host_info, port=port_info)
cursor = conn.cursor()
cursor.execute(...) #table information
a = cursor.fetchall()
# rfm analysis
# draw the chart
for i, bar in enumerate(bars):
value = bar.get_width()
if segments_counts.index[i] in ['重要价值用户']:
bar.set_color('firebrick')
ax.text(value,
bar.get_y() + bar.get_height()/2,
'{:,} ({:}%)'.format(int(value),
int(value*100/segments_counts.sum())),
va='center',
ha='left'
)
return plt.show()
那么给功能添加进度条有什么好办法呢?
tqdm进度条可能是Python中最有特色的进度条了。您只需使用
pip install tqdm
即可安装。
以下代码演示了它是多么容易使用。
from tqdm import tqdm
import time
for i in tqdm(range(100)):
time.sleep(0.1)
这就是在 pycharm 中运行上面的代码示例后的样子:
1:完成百分比
2:进度条
3:总迭代中的当前迭代
4:流逝的时间
5:预计剩余时间
6:每秒处理的迭代次数
使用
rich
,我们可以添加一个进度条,该进度条会在给定函数时更新。这是一个例子:
from rich.progress import Progress
import time
import inspect
def run(func, sleep=0):
update = lambda progress, task: progress.update(task, advance=1)
function = inspect.getsource(func)
mylist = function.split('\n')
mylist.remove(mylist[0])
length = len(mylist)
for num, line in enumerate(mylist):
mylist[num] = line[8:] + "\nupdate(progress, task)\ntime.sleep(sleep)" #update the progress bar
myexec = ''
for line in mylist:
myexec += line + '\n'
with Progress() as progress:
task = progress.add_task("Working...", total=length)
exec(myexec)
if __name__ == '__main__':
def myfunc():
#chose to import these modules for progress bar example since they take a LONG time to import on my computer
import pandas
import openai
run(myfunc)
我不会完全解释它是如何工作的,但基本上函数
run()
接受另一个函数作为参数,以及更新进度条之间的睡眠时间。然后,我们使用 inspect
将函数转换为字符串,并添加额外的内容以在函数的每一行之后更新进度条,并使用 exec()
运行该函数。
虽然这段代码效率有点低(特别是因为它使用了
exec()
),但它确实有效。我建议将其保存为文件,也许可以称之为progress_bar
?然后,您可以使用 run()
函数从 python 文件中的任何位置运行此进度条。
所以就你而言,我假设你想要:
from name_of_progress_bar_module import run
run(rfm_chart) #run the function, with default sleep time 0 between progress bar updating
您可能应该注意到,
rich
在终端中看起来最好。否则...它有效...但看起来不太好。