跳至内容
Python

Python 进度条:完整指南与示例

学习如何使用 tqdm、progressbar2、alive-progress 和 Tkinter 创建 Python 进度条,并通过最佳实践提升用户体验与应用性能。
Mark Pedigo's photo
Mark Pedigo
已更新 · 13分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

在当今的应用中,用户希望得到即时反馈,尤其是当任务需要较长时间才能完成时。Python 进度条是一种清晰、易用的方式,用于显示后台正在进行的操作。一个设计得当的进度条能够让程序显得更快、更专业,并提升友好度。 

本文将介绍如何使用 tqdm、progress、progressbar2、alive-progress 和 Tkinter 等常用库来实现 Python 进度条,并给出提升用户体验与应用性能的最佳实践。

如果您想通过动手实践进一步学习 Python 概念,欢迎查看我们的Python 编程基础技能路径。

要点速览

  • 对于命令行工具,tqdm 是首选——轻量且与 pandas 配合良好。简单脚本可用 progress,需要自定义布局时用 progressbar2,而追求动效视觉可选 alive-progress。

  • 针对桌面应用,Tkinter 内置的 ttk.Progressbar 同时支持已知时长(确定型)和未知时长(不确定型)的任务。

  • 在高速循环中限制更新频率,避免拖慢程序;并将可视化与百分比或计数等文本结合,让进度条对所有人都实用。

什么是 Python 中的进度条?

进度条随处可见。它们常用于文件下载、软件安装以及ETL 管道。它们也常用于跟踪机器学习模型训练的进度。

进度条会显示任务已完成的部分及剩余部分。它既可以以文本形式出现在命令行界面(CLI),也可以作为图形用户界面(GUI)中的可视化条形。

进度条能提升用户体验。它们提供实时更新,向用户展示当前进展。如果发生延迟,用户可以决定是干预还是等待。这种可见性能减少挫败感,让等待显得更短。用户不必盯着静止的屏幕猜测是否在运行;他们能保持参与,并确信进度在推进。

开发者使用进度条来跟踪应用性能。它们有助于发现瓶颈、基准测试代码并跟踪任务时长。在脚本和工作流中,进度条提供明确的状态更新,帮助用户更好地理解长时间运行的过程,同时也提升交互式工具和笔记本的可用性。

进度条也可作为一种简单的性能监测手段。它们展示每个任务耗时,帮助开发者定位缓慢阶段并衡量效率,从而便于比较不同实现方式。

命令行进度条

命令行进度条在终端中直接为长时间任务提供可视化反馈,使脚本更具信息量且更易用。Python 提供了多种库,各自在速度、自定义性和视觉风格方面各有优势。我们将介绍其中四种:tqdm、progress、progressbar2 和 alive-progress。 

Tqdm:速度与简洁的标准之选

tqdm 是 Python 中广受欢迎的进度条库。它为循环和可迭代对象提供快速而多样的进度指示器。它会跟踪迭代次数并计算剩余时间与已用时间,并实时更新进度条。tqdm 在后台运行,会预测剩余时间并跳过不必要的更新。它易学、内存占用小,并且拥有强大的社区支持。 

安装流程

安装 tqdm 最简单的方式是使用 pip 安装器。在终端输入以下命令。

pip install tqdm

打印版本号以确保库已正确安装。

import tqdm
print(tqdm.__version__)

4.67.1

tqdm 的基本用法

tqdm 使用非常简单。导入库后,将任意可迭代对象用 tqdm(iterable) 包裹即可显示进度条。

相比编写 tqdm(range(n)),您可以使用简写 trange(n),更为便捷。

from tqdm import trange
import time

for _ in trange(100, desc="Processing"):
    # Do stuff here
    time.sleep(0.05)  # simulate a task

该代码在执行期间会显示实时进度条。

该进度条展示:

  • 完成百分比(22%)
  • 已完成迭代次数/总次数(224/1000)
  • 已用时间与预计剩余时间(已用 12 秒,剩余 42 秒)
  • 每秒迭代数(18.09 it/s)。

为进度条添加描述,可指定 desc 选项。

for i in trange(1000, desc='Processing'):  # description
    # Simulate a task
    time.sleep(0.05)

嵌套进度条 

tqdm 的嵌套进度条可帮助您跨多个循环跟踪进度,也适用于需要跟踪多个工作阶段的场景,如批处理、嵌套循环和模型训练。 

将每一层循环都用 tqdm 包裹,并通过 position 与 leave 参数控制其显示方式。

  • position:设置每个进度条的垂直位置。position=0 为最上方的进度条,position=1 则显示在其下方,依此类推。
  • leave:若 leave=True,进度条完成后保留在屏幕上;若 leave=False,为避免杂乱则会消失。
for i in trange(3, desc='Outer loop', leave=True):
    for j in trange(5, desc='Inner loop', leave=False):
        for j in trange(4, desc='Inner inner loop', leave=False):
            time.sleep(0.05)

嵌套进度条呈现清晰的层次结构,有助于可视化任务的不同阶段,并在多个层级提供细致洞察,从而帮助开发者轻松识别卡顿或瓶颈。

与 Pandas 的集成

Tqdm 与 pandas 集成良好,可为 DataFrame 和 Series 任务轻松加入进度条,实时展示 apply、groupby、map 等函数的进展,这些函数在大数据集上可能较慢。

启用该功能时调用 tqdm.pandas(),然后用 progress_apply 替代 pandas 常规的 apply 方法。函数在按行或按列运行时会显示进度条,您无需重写代码即可看到操作进展。

在下面的程序中,我们创建了一个名为 "numbers" 的列,其中包含 0 到 1000 的整数。随后通过一个名为 slow_squared 的“慢速”操作生成新列。 

我们不使用标准的 pandas apply,而是使用 tqdm 的 progress_apply。在操作期间会出现进度条,实时显示处理完成的比例。

import pandas as pd
from tqdm import tqdm
import time

# Simulate a time-consuming operation
def slow_square(x):
    time.sleep(0.01)
    return x**2

# Create a sample DataFrame
df = pd.DataFrame({'numbers': range(1000)})

# Initialize tqdm for pandas
tqdm.pandas(desc="Processing")

# Use progress_apply instead of apply
df['slow_squared'] = df['numbers'].progress_apply(slow_square)
# Print the result
print(df.head())

代码输出如下所示。

我们也可以将 progress_apply 用于 groupby 等其他 DataFrame 操作。

grouped = df.groupby('numbers').progress_apply(lambda g: g.sum())

自定义选项

Tqdm 允许根据不同环境与用户需求自定义进度条。您可以用 ncols 调整宽度;bar_format 参数可完全控制文本布局;设置 dynamic_ncols=True 则可让进度条自动适配终端宽度。

tqdm 的性能考量

Tqdm 快速且轻量,即使在高速循环中开销也很小。可通过 disable=True 禁用进度条,这在性能关键的生产环境中很有用。对于高速循环,每次更新进度条可能代价过高,因此 tqdm 允许用 mininterval 和 maxinterval 等参数控制更新频率。 

Progress:可定制样式与旋转指示器

Python 的Progress 库可以在命令行中创建简单的纯文本进度条。其 API 简洁,支持进度条与旋转指示器(spinner),并允许基本的输出自定义。它体积小、速度快、无依赖,非常适合快速脚本和简单场景。 

progress 库内置七种进度条样式:Bar、ChargingBar、FillingSquaresBar、FillingCirclesBar、IncrementalBar、PixelBar 和 Shadybar。 

安装方式:使用 pip。

pip install progress

使用时,导入所需样式,实例化对象,在循环中调用 .next(),完成后调用 .finish()。例如使用 ChargingBar:

import time
from progress.bar import ChargingBar
bar = ChargingBar('Processing', max=20)
for i in range(20):
    # Do some work
    time.sleep(0.5)
    
    bar.next()
bar.finish()
`

Progress 也包含用于未知时长任务的旋转指示器。实现 spinner 的代码也很直观。

import time
from progress.spinner import Spinner

spinner = Spinner('Processing... ')

# Spinner during a task of unknown duration.
for _ in range(50): 
    # Do stuff 
    time.sleep(0.1)  # simulate a running task

    spinner.next()

spinner.finish()

该代码会显示描述(“Processing…”)以及后续的旋转指示器。

progress 库简单轻量,但也有一些限制:不支持 Jupyter 笔记本,且不能动态调整尺寸;自定义选项也少于 tqdm 等库。它适合基础命令行任务,但在复杂或高性能需求的作业中可能力不从心。

Progressbar2:更强的自定义与兼容性

Progressbar2 是一款功能强大的 Python 库,帮助您为命令行应用创建灵活且可定制的进度条。它内置众多小部件(widget),如百分比、预计完成时间(ETA)、动画标记和计数器,非常适合更复杂或更精致的 CLI 任务。 

相较于更简单的 progress,Progressbar2 提供了更强的控制和格式化选项,并且与日志与多线程工作流的配合更好。

安装方式:使用 pip。

pip install progressbar2

progressbar2 中的 ProgressBar 类通过一组可定制的小部件展示当前进度状态。 

小部件是随进度条状态更新的模块化组件,包括完成百分比、已用时间和预计剩余时间等。 

可选小部件非常丰富,包括文本标签、进度标记、计数器、计时器、旋转指示器以及自定义格式器。通过组合这些组件,您可以根据应用需求灵活定制外观与功能。

Progressbar2 的基本用法相当简单。 

import time
import progressbar

for i in progressbar.progressbar(range(1000)):
    time.sleep(0.02)

输出会显示完成百分比、已完成/总迭代次数、已用时间和预计剩余时间。

进度条库通常依赖回车符(\r)在终端中更新同一行,这意味着常规的 print() 语句可能会将进度条顶下去或破坏其输出。progressbar2 提供了在不干扰进度条的情况下安全打印消息的方式。

import time
import progressbar

bar = progressbar.ProgressBar(redirect_stdout=True)
for i in range(10):
    # Do some task
    time.sleep(0.1)

    # Print statement
    print(f'Loop #{i}')
    bar.update(i)

progressbar2 通过模块化小部件系统提供了广泛的自定义能力。小部件可显示完成百分比、已用时间、预计剩余时间、计数器或动画条等信息。您可自由组合,打造自定义进度条,例如只显示百分比与 ETA,或加入文件名、时间戳、旋转指示器等更多细节。 

import time
import progressbar

# Define a custom set of widgets
widgets = [
    'Progress: ',                                # Description text
    progressbar.Percentage(),         # Show percentage completed
    ' ',                              
    progressbar.Bar(marker=':'),      # Custom bar with specified marker
    ' ',
    progressbar.ETA(),                    # Estimated time remaining
    ' | ',
    progressbar.Timer(),                  # Time elapsed
]

# Initialize the progress bar with widgets
bar = progressbar.ProgressBar(widgets=widgets, max_value=50)

# Task
for i in range(50):
    # Do stuff
    time.sleep(0.1)  # Simulate task
    
    bar.update(i + 1)

Alive-progress:为现代终端打造的动态动画

Alive-progress 提供实时变化的动画进度条,为命令行应用带来现代、灵动的观感。进度条会前进并显示实用的实时指标,如完成百分比、已用时间、预计剩余时间与迭代速度,兼具美观与信息量。

要安装 alive-progress 库,请使用 pip 安装。

pip install alive-progress

如其 GitHub 页面所示,若要查看功能演示,可运行以下代码。

from alive_progress.styles import showtime

showtime()

您将看到类似如下的输出。

Alive-progress 还能同时显示并管理多个进度条。

from alive_progress import alive_bar
import time
import threading

# Simulate a task
def simulate_task(name, total):
    with alive_bar(total, title=name) as bar:
        for _ in range(total):
            # Do something
            time.sleep(0.5)

            bar()

# Define threads
threads = [
    threading.Thread(target=simulate_task, args=('Task A', 50)),
    threading.Thread(target=simulate_task, args=('Task B', 70)),
    threading.Thread(target=simulate_task, args=('Task C', 40)),
]

# Start each thread
for t in threads:
    t.start()

# Block the main thread until the program is finished
for t in threads:
    t.join()

alive-progress 库包含多种内置主题。主题会控制动画风格、进度条填充字符以及整体运动效果。常见主题包括 classic、pulse 和 brackets。

import time
from alive_progress import alive_bar

with alive_bar(100, bar='blocks') as bar:
    for _ in range(100):
        # Do something
        time.sleep(0.02)
        
        bar()

暂停/恢复——可临时停止并恢复进度而不丢失状态

from alive_progress import alive_bar
import time

# Run a task...
with alive_bar(100) as bar:
    for i in range(50):
        # Do something
        time.sleep(0.02)

        bar()
    
    # Pause
    bar.text('Temporarily pausing...')
    time.sleep(1)

    # Resume
    bar.text('Resuming...')
    for i in range(50):
        time.sleep(0.02)
        bar()

使用 Tkinter 的 GUI 进度条

Tkinter 是 Python 的标准 GUI(图形用户界面)工具包。其设计内置了许多可直接使用的功能,无需额外安装。您可以创建窗口、按钮、文本框、菜单、进度条等。Tkinter 非常适合构建简单桌面应用、交互式工具与原型。 

使用以下代码即可创建一个基础进度条。 

import tkinter as tk
from tkinter import ttk
import time

def start_progress():
    progress["value"] = 0
    root.update_idletasks()
    for i in range(101):
        time.sleep(0.02)
        progress["value"] = i
        root.update_idletasks()

# Set up the window
root = tk.Tk()
root.title("Progress Bar")
root.geometry("300x100")

# Create a progress bar
progress = ttk.Progressbar(root, orient="horizontal", length=250, mode="determinate")
progress.pack(pady=20)

# Create a start button
start_button = ttk.Button(root, text="Start", command=start_progress)
start_button.pack()

# Start the tkinter loop
root.mainloop()

在我的 Mac 上的输出:

ttk.Progressbar 提供两种模式:确定型(determinate)与不确定型(indeterminate)。当任务的时长或步骤数已知时使用确定型;当任务时长未知或无法按步骤衡量时使用不确定型。

上述代码为确定型示例,因为我们知道任务长度为 250 步。下面是不确定型的示例。

import tkinter as tk
from tkinter import ttk
import time
import threading

def start_indeterminate():
    def run():
        # 10 ms between moves
        progress.start(10)

        # Simulate task of unknown duration
        time.sleep(10)

        # Stop
        progress.stop()
    
    # Run in a thread, else the tkinter GUI loop is unresponsive
    threading.Thread(target=run).start()

# Set up the GUI
root = tk.Tk()
root.title("Indeterminate Progress Bar")
root.geometry("300x100")

# Create an indeterminate progress bar
progress = ttk.Progressbar(root, mode='indeterminate', length=250)
progress.pack(pady=20)

# Start button
start_button = ttk.Button(root, text="Start", command=start_indeterminate)
start_button.pack()

# Run the tkinter loop
root.mainloop()

请注意,进度条在独立线程中运行。若直接在主线程中调用 run(),time.sleep() 会阻塞 Tkinter 的主事件循环,导致整个 GUI 冻结,包括按钮点击、窗口重绘以及进度条动画。

性能考量与优化

应当为进度条选择哪种库?部分取决于您的开销要求与使用场景。

库

开销

使用场景

tqdm

极低

高速循环、数据管道,对性能影响最小

progress

低

简单 CLI 脚本,轻量且无依赖

progressbar2

中等

自定义布局、ETA 与日志;在高速任务中略有放缓

alive-progress

中到高

视觉效果丰富、多条进度、平滑动画;更适合长任务

为提升性能,请优化更新频率。一种方法是不要在每次迭代都更新进度条,特别是在快速或高频循环中。使用条件逻辑每 N 步更新一次,例如每 100 次迭代更新。

在性能关键或生产环境中,若无需可视化反馈,可禁用进度条。这样能节省资源,同时仍保持开发或调试时的一致逻辑。 

减少 I/O 操作对性能至关重要。向终端、磁盘或网络输出都会变慢。以下是一些在性能关键任务中降低 I/O 的策略:

  • 缓冲输出,批量写入而非每次迭代都写。
  • 仅在固定间隔或特定条件下更新。
  • 尽量减少或禁用循环内的 print()。
  • 在生产环境中添加标志以抑制不必要输出。
  • 使用线程或多进程将 I/O 与计算分离。
  • 压缩或批量处理大写入以降低磁盘 I/O 频率。

高效进度条的最佳实践

下面总结在 Python 中创建进度条时应牢记的一些最佳实践。 

为什么要使用进度条?

在应用中使用进度条有诸多好处。首先,它们提供实时反馈,安抚用户情绪,让其确信任务正在推进并减少不确定性。这种可见性提升用户体验,让等待时间显得更短、交互更直观。 

其次,通过可视化跟踪任务完成度,进度条让性能监控更容易,使用户与开发者在长时间运行操作中能够快速发现瓶颈或停滞。最后,引入进度条还能提升应用界面的专业度,传达清晰度与以用户为中心的设计理念。

已知 vs. 未知时长的任务

对于有固定时长的任务(如文件处理、循环或机器学习训练的 epoch),请使用确定型进度条。它会基于可度量的进展进行填充,为用户提供剩余工作量的清晰感知。

对于未知时长的任务(如 API 调用或后台检查),请使用旋转指示器或不确定型进度条。即使无法预测耗时,它们也能提供“正在进行中”的视觉提示。

我该用哪个库?

应使用的库取决于您要完成的任务。

任务 

库

备注

高频循环

tqdm

轻量高效;使用 mininterval 降低更新频率

一次性简单脚本

progress

配置最少、无依赖,适合快速任务

结构化或自定义输出

progressbar2

基于小部件,支持 ETA、计时器与布局控制

多阶段或嵌套任务

tqdm,alive-progress

支持嵌套进度条或多条进度展示,适合分层任务

追求视觉精致的 CLI 脚本

alive-progress

动画现代、体验流畅

GUI 应用

tkinter

内置 GUI 工具包,支持确定型与不确定型进度条

自定义

自定义进度条时要关注清晰度与信息价值,并在两者间取得平衡。简洁明了、包含关键指标的进度条,通常优于信息堆叠、杂乱无章的设计。 

您可以使用 progressbar2 和 alive-progress 等库来自定义进度条的布局、颜色与动画。通过主题或格式化提升体验,同时避免用过多小部件或复杂视觉造成干扰。目标是提供有用反馈,而非分散注意力或让用户不知所措。

异常处理与兼容性测试

用 try-except 包裹进度条逻辑,防止在任务出错时出现 UI 闪烁或崩溃。这对长时间运行脚本或依赖不确定外部依赖的场景尤为关键。

此外,请在不同环境中测试进度条,如不同操作系统、终端类型与显示宽度,确保行为一致。

部分库在 Jupyter 笔记本、远程终端或 GUI Shell 中的表现会有差异。及早验证兼容性有助于避免意外问题,确保生产环境中的顺畅体验。

无障碍考虑

创建进度指示器时,应考虑无障碍性,以确保所有用户都能获得清晰反馈。建议如下:

  • 不要仅依赖颜色或动画来展示进度;增加百分比、步数或时间估计等文本元素。
  • 使用清晰、高对比度的视觉元素以提升可读性。
  • 确保 GUI 应用中的进度条与屏幕阅读器良好兼容。
  • 对于命令行工具,考虑提供详细级别选项,以纯文本打印进度更新。

重视无障碍不仅提升可用性,也让您的工具更具包容性与专业性。

结语 

进度条是任何 Python 应用中简单却有力的特性。它们提供即时反馈、改善用户体验,同时有助于跟踪性能与提升代码清晰度。选择合适的进度条库至关重要——无论您是在编写快速脚本、命令行工具,还是完整的 GUI 应用。经过深思熟虑的实现能提升软件的速度、专业度与易用性。将自定义、性能、兼容性与无障碍放在优先位置,能让进度条不止于视觉元素,而成为用户参与您的作品的重要桥梁。

想要继续学习,请查看以下资源:

Python 进度条常见问答

什么是进度条?

进度条是一种可视化指示器,用于展示任务已完成的部分与剩余部分。它通过在长时间操作期间提供反馈来改善用户体验。

Python 中流行的进度条库有哪些?

最常见的库有 tqdm、progress、progressbar2 和 alive-progress。

我可以在 pandas 中使用进度条吗?

可以。tqdm 可通过 progress_apply()(替代 apply)等方法与 pandas 集成。

我可以自定义进度条的外观吗?

可以。tqdm 与 progressbar2 等库可自定义布局、宽度、颜色和更新频率。

我应该在 Jupyter Notebooks 中使用哪个库?

tqdm.notebook 与 Jupyter 集成良好。


Mark Pedigo's photo
Author
Mark Pedigo
LinkedIn

Mark Pedigo(博士)是一位在医疗数据科学、编程与教育领域具有深厚专长的资深数据科学家。Mark 拥有数学博士学位、计算机科学学士学位以及人工智能专业证书,兼具扎实的技术底蕴与务实的解决问题能力。他的职业经历涵盖欺诈检测、婴儿死亡率预测与财务预测,并参与了 NASA 成本估算软件的研发。作为教育工作者,他曾在 DataCamp 和圣路易斯华盛顿大学任教,并指导初级程序员。在闲暇时间,Mark 与妻子 Mandy 和爱犬 Harley 一起享受明尼苏达的户外时光,并演奏爵士钢琴。

主题
Python

热门 Python 课程

学习路径

Python 编程基础

16 小时
提升你的 Python 编程技能。 学习如何使用模块和包、使用内置数据类型,以及编写自定义函数。
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多