You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现固定在stdout顶部的粘性进度条

Python实现固定顶部的进度条(类似apt升级效果)

需求说明:实现进度条固定在终端顶部,下方内容逐行打印时,进度条始终保持在顶部位置不被挤走,类似Linux下apt upgrade的交互逻辑(注:实际apt进度条在底部,此处需求为进度条固定顶部)。

期望效果示例

Setting up python3-aiodns (3.0.0-2) ...
Setting up libpython3-all-dev:arm64 (3.11.2-1+b1) ...
Setting up python3-dev (3.11.2-1+b1) ...
Setting up theharvester (4.2.0-0kali2) ...
Setting up faraday (4.3.5-0kali1) ...
faraday.service is a disabled or a static unit not running, not starting it.
Setting up samba-common-bin (2:4.17.7+dfsg-1) ...
Setting up python3-aesedb (0.1.3+git20230221.9b7c468-0kali1) ...
Setting up samba (2:4.17.7+dfsg-1) ...
nmbd.service is a disabled or a static unit not running, not starting it.
samba-ad-dc.service is a disabled or a static unit not running, not starting it.
smbd.service is a disabled or a static unit not running, not starting it.
Setting up python3-all-dev (3.11.2-1+b1) ...
Setting up kali-linux-headless (2023.2.5) ...
Setting up python3-pypykatz (0.6.6-0kali1) ...
Setting up kali-linux-default (2023.2.5) ...
Processing triggers for systemd (252.6-1) ...
Processing triggers for man-db (2.11.2-2) ...

Progress: [ 99%] [#########################################################.] 

用户尝试的代码

import time

def print_progress_bar(iteration, total):
    percent = "{:.1f}".format(100 * (iteration / float(total)))
    filled_length = int(50 * iteration // total)
    bar = "█" * filled_length + "-" * (50 - filled_length)
    print(f"\033[F\033[KProgress: |{bar}| {percent}% Complete")

for i in range(1, 101):
    print_progress_bar(i, 100)
    print(i, end=" ")
    time.sleep(0.1)

问题分析

这段代码的核心问题在于:

  1. 使用\033[F回到上一行时会覆盖之前打印的内容,无法保留历史输出
  2. print(i, end=" ")设置了不换行,导致内容无法逐行展示

解决方案

利用终端ANSI控制码实现光标位置的保存、恢复和行操作,确保进度条始终停留在顶部,内容在下方逐行打印:

import time

def update_top_progress(iteration, total):
    # 计算进度参数
    percent = "{:.1f}".format(100 * (iteration / float(total)))
    filled_length = int(50 * iteration // total)
    bar = "█" * filled_length + "-" * (50 - filled_length)
    
    # 保存当前光标位置,避免更新进度条时丢失内容输出位置
    print("\033[s", end="")
    # 移动光标到终端第一行开头(进度条固定位置)
    print("\033[1;1H", end="")
    # 清空当前行内容,避免进度条残留旧数据
    print("\033[K", end="")
    # 打印更新后的进度条
    print(f"Progress: |{bar}| {percent}% Complete")
    # 恢复之前保存的光标位置,回到内容输出区域继续打印
    print("\033[u", end="")

# 初始化顶部进度条
print("Progress: |--------------------------------------------------| 0.0% Complete")
# 换行到内容输出区域
print()

# 模拟业务内容逐行输出+进度条更新
for i in range(1, 101):
    update_top_progress(i, 100)
    # 打印实际业务内容,逐行展示
    print(f"Setting up package-{i} ... Processing")
    time.sleep(0.1)

关键控制码说明

  • \033[s:保存当前光标位置
  • \033[1;1H:将光标移动到终端第一行的开头
  • \033[K:清空当前行的所有内容
  • \033[u:恢复之前保存的光标位置

内容的提问来源于stack exchange,提问作者federikowsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:47:09