在控制台中重写多行
- 2024-12-31 08:38:00
- admin 原创
- 49
问题描述:
我知道可以用“\r”一致地重写终端上显示的最后一行,但我无法弄清楚是否有办法返回并编辑控制台中打印的先前的行。
我想做的是重印多行用于基于文本的 RPG,然而,我的一位朋友也对此感到疑惑,因为有一个应用程序,其中一行专用于进度条,另一行描述下载。
即控制台将打印:
Moving file: NameOfFile.txt
Total Progress: [######## ] 40%
然后在程序运行时进行适当的更新(对两行)。
解决方案 1:
在 Unix 上,使用curses模块。
在 Windows 上,有几种选择:
上面链接的 HOWTO 推荐使用控制台模块
http://new Centurycomputers.net/projects/wconio.html
http://docs.activestate.com/activepython/2.6/pywin32/win32console.html
使用 curses 的简单示例(我完全是 curses 新手):
import curses
import time
def report_progress(filename, progress):
"""progress: 0-10"""
stdscr.addstr(0, 0, "Moving file: {0}".format(filename))
stdscr.addstr(1, 0, "Total progress: [{1:10}] {0}%".format(progress * 10, "#" * progress))
stdscr.refresh()
if __name__ == "__main__":
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
try:
for i in range(10):
report_progress("file_{0}.txt".format(i), i+1)
time.sleep(0.5)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
解决方案 2:
像这样:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
for t in range(20):
time.sleep(0.5)
s = "update %d" % t
for _ in range(len(queue)):
sys.stdout.write("x1b[1Ax1b[2K") # move up cursor and delete whole line
queue.append(s)
for i in range(len(queue)):
sys.stdout.write(queue[i] + "
") # reprint the lines
我在用 Go 编写的Jiri项目中发现了这一点。
更好的是:完成后删除所有行:
#!/usr/bin/env python
import sys
import time
from collections import deque
queue = deque([], 3)
t = 0
while True:
time.sleep(0.5)
if t <= 20:
s = "update %d" % t
t += 1
else:
s = None
for _ in range(len(queue)):
sys.stdout.write("x1b[1Ax1b[2K") # move up cursor and delete whole line
if s != None:
queue.append(s)
else:
queue.popleft()
if len(queue) == 0:
break
for i in range(len(queue)):
sys.stdout.write(queue[i] + "
") # reprint the lines
解决方案 3:
最终,如果您想操纵屏幕,您需要使用底层操作系统库,通常是:
Linux 或 OSX 上的 curses(或 terminfo/termcap 数据库跟踪的底层终端控制代码)
Windows 上的 win32 控制台 API。
如果您不介意坚持使用一个操作系统或乐于在 Windows 上安装第三方库,@codeape 的回答已经为您提供了许多选项。
但是,如果您想要一个可以简单地 pip 安装的跨平台解决方案,则可以使用asciimatics。作为开发此包的一部分,我必须解决环境之间的差异,以提供适用于 Linux、OSX 和 Windows 的单一 API。
对于进度条,您可以使用 BarChart 对象,如本演示中使用此代码所示。
解决方案 4:
这是一个适用于 Python 2/3 的 Python 模块,它可以用几行代码简单地解决这种情况;D
reprint - Python 2/3 的一个简单模块,用于在终端中打印和刷新多行输出内容
您可以简单地将该output
实例视为普通dict
实例list
(取决于您使用的模式)。当您修改output
实例中的内容时,终端中的输出将自动刷新 :D
根据您的需要,这里是代码:
from reprint import output
import time
if __name__ == "__main__":
with output(output_type='dict') as output_lines:
for i in range(10):
output_lines['Moving file'] = "File_{}".format(i)
for progress in range(100):
output_lines['Total Progress'] = "[{done}{padding}] {percent}%".format(
done = "#" * int(progress/10),
padding = " " * (10 - int(progress/10)),
percent = progress
)
time.sleep(0.05)
解决方案 5:
回车键可用于转到行首,ANSI 代码ESC A
( "[A"
) 可用于向上一行。这在 Linux 上有效。它可以在 Windows 上工作,方法是使用colorama
软件包启用 ANSI 代码:
import time
import sys
import colorama
colorama.init()
print("Line 1")
time.sleep(1)
print("Line 2")
time.sleep(1)
print("Line 3 (no eol)", end="")
sys.stdout.flush()
time.sleep(1)
print("
Line 3 the sequel")
time.sleep(1)
print("[ALine 3 the second sequel")
time.sleep(1)
print("[A[A[ALine 1 the sequel")
time.sleep(1)
print() # skip two lines so that lines 2 and 3 don't get overwritten by the next console prompt
print()
输出:
> python3 multiline.py
Line 1 the sequel
Line 2
Line 3 the second sequel
>
在底层,colorama 大概可以使用 启用控制台虚拟终端序列SetConsoleMode
。
(也发布在这里:https: //stackoverflow.com/a/64360937/461834)
解决方案 6:
您可以尝试tqdm。
from time import sleep
from tqdm import tqdm
from tqdm import trange
files = [f'file_{i}' for i in range(10)]
desc_bar = tqdm(files, bar_format='{desc}')
prog_bar = trange(len(files), desc='Total Progress', ncols=50, ascii=' #',
bar_format='{desc}: [{bar}] {percentage:3.0f}%')
for f in desc_bar:
desc_bar.set_description_str(f'Moving file: {f}')
prog_bar.update(1)
sleep(0.25)
还有嵌套进度条功能tqdm
from tqdm.auto import trange
from time import sleep
for i in trange(4, desc='1st loop'):
for k in trange(50, desc='2rd loop', leave=False):
sleep(0.01)
请注意,嵌套进度条tqdm
存在一些已知问题:
控制台一般:需要支持将光标移动到上一行。例如,IDLE、ConEmu和PyCharm(也包括此处、此处和此处)缺乏全面支持。
Windows:另外可能还需要 Python 模块
colorama
来确保嵌套的条形图停留在各自的行内。
对于 Python 中的嵌套进度条,Python 中的双进度条 - Stack Overflow有更多信息。
解决方案 7:
我发现了一个使用“magic_char”的简单解决方案。
magic_char = '[F'
multi_line = 'First
Second
Third'
ret_depth = magic_char * multi_line.count('
')
print('{}{}'.format(ret_depth, multi_line), end='', flush = True)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件