在Python脚本中运行多个串行任务时,经常会遇到多个进度条依次出现导致输出重叠的问题,第二个进度条出现时如果不处理之前的输出,会让终端内容杂乱无章,影响查看进度。我们可以通过几种不同的方式实现清空指定区域输出的效果。

使用tqdm库的leave参数控制
tqdm是Python中最常用的进度条库,它自带的leave参数可以直接控制进度条完成后是否保留在终端中。如果第一个进度条执行完成后设置leave=False,那么第一个进度条结束时会自动清空自身所在的输出区域,第二个进度条出现时就不会有重叠问题。
示例代码如下:
from tqdm import tqdm
import time
# 第一个任务进度条,完成后不保留
for i in tqdm(range(50), desc="第一个任务", leave=False):
time.sleep(0.05)
# 第二个任务进度条
for i in tqdm(range(50), desc="第二个任务"):
time.sleep(0.05)手动清空指定行输出
如果需要更灵活地控制清空的区域,比如只清空前两行的输出,而不是整个进度条区域,可以使用终端控制序列来操作光标位置,再输出空内容覆盖原有内容。
不同系统的终端控制方式略有差异,下面是针对类Unix系统和Windows系统的通用实现:
import sys
import time
def clear_lines(n=1):
# 光标上移n行
sys.stdout.write(f"\033[{n}A")
# 清空光标所在行及之后的内容
sys.stdout.write("\033[J")
sys.stdout.flush()
# 模拟第一个进度条输出
print("第一个任务进度:50%")
print("当前处理文件:test1.txt")
time.sleep(1)
# 清空上面两行输出
clear_lines(2)
# 模拟第二个进度条输出
print("第二个任务进度:30%")
print("当前处理文件:test2.txt")两种方式的选择建议
如果使用的是tqdm库生成进度条,优先选择第一种方式,配置简单且不需要处理不同系统的兼容问题。如果是自定义的进度条输出,或者需要清空非进度条的指定区域内容,第二种手动控制的方式会更灵活,适配更多场景。
| 实现方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| tqdm leave参数 | 使用tqdm生成进度条的场景 | 配置简单,兼容性好 | 只能控制整个进度条的保留状态 |
| 手动控制终端序列 | 自定义输出、需要精确控制清空区域的场景 | 灵活度高,可指定清空行数 | 需要处理不同系统的终端差异 |
注意事项
- 使用终端控制序列时,部分老旧终端可能不支持相关指令,需要提前测试兼容性。
- tqdm的
leave=False参数只在进度条正常结束时生效,如果脚本异常退出,进度条可能还是会保留在终端中。 - 如果输出内容包含换行,计算需要清空的行数时要包含换行产生的空行,避免清空不彻底。