Python如何实现多行可刷新且互不覆盖的控制台进度输出
多线程终端多行进度条覆盖修复方案
问题原因
你当前代码中所有线程都使用\r将光标定位到当前行首输出,三个线程无协调抢占同一行输出,自然会出现内容互相覆盖的情况。
修复方案
采用ANSI终端转义序列+线程锁的方案实现,不需要引入额外第三方库,兼容绝大多数主流终端:
实现思路
- 提前在终端预留3行位置用于展示三个进度
- 用ANSI转义码控制光标定位到每个进度对应的固定行更新内容
- 加线程锁保证每次输出的原子性,避免多个线程同时操作光标导致错位
修复后可运行代码:
import sys import time import threading # 线程锁,保证单次输出操作原子性,不会被其他线程打断 output_lock = threading.Lock() # ANSI转义序列:光标上移n行 def cursor_up(n): return f"\x1b[{n}A" # ANSI转义序列:光标下移n行 def cursor_down(n): return f"\x1b[{n}B" # ANSI转义序列:清除当前行到行尾的内容 def clear_line(): return "\x1b[0K" # 提前输出3个换行,占用3行进度条的位置 print("\n"*2) def first(): for i in range(50,0,-1): with output_lock: # 定位到第一行进度位更新内容 sys.stdout.write(cursor_up(3)) sys.stdout.write(f"The current chicken is: {i:<3d}" + clear_line() + "\n") # 光标复位到最底部避免输出错位 sys.stdout.write(cursor_down(2)) sys.stdout.flush() time.sleep(1) def second(): for i in range(100,0,-1): with output_lock: # 定位到第二行进度位更新内容 sys.stdout.write(cursor_up(3)) sys.stdout.write(cursor_down(1)) sys.stdout.write(f"The current number is: {i:<3d}" + clear_line() + "\n") sys.stdout.write(cursor_down(1)) sys.stdout.flush() time.sleep(1) def third(): for i in range(1000,0,-1): with output_lock: # 定位到第三行进度位更新内容 sys.stdout.write(cursor_up(3)) sys.stdout.write(cursor_down(2)) sys.stdout.write(f"The current cow is: {i:<3d}" + clear_line() + "\n") sys.stdout.flush() time.sleep(1) awidj = [first, second, third] for thread in awidj: threading.Thread(target=thread).start()
注意事项
- Windows 10以下旧版CMD默认关闭ANSI转义支持,可在代码开头导入os模块后执行
os.system('')开启支持 - 每次输出后调用
sys.stdout.flush()强制刷新缓冲区,避免内容延迟显示 - 代码中加入的行清除逻辑是为了避免数字位数变化时残留旧字符
内容的提问来源于stack exchange,提问作者Lugaw
相关产品推荐
相关产品推荐

