我有一个在Windows 7上运行的脚本,时间较长(几分钟)。我想在更多行上使用进度条和其他一些信息(意味着\r
在这里没用,因为我需要多行)。我写了一个应该包装一个iterable的生成器,每次调用“重置”控制台左上角的光标位置到进度条,可以重写信息。
import colorama
def progress_bar(iterable: typing.Iterable, length: int = 100):
""" Takes an iterable and acts as a generator that prints a progress barr each time it yields.
Splits the iterable and uses one of the copies to get the length of the iterable(consuming the copy in the
process) before using the second to iterate trough the items, clearing the screen each time and reprinting the
progress bar before yielding a new item.
Intended use is as a wrapper for any iterable that is desired to have a progress bar when being iterated over.
Args:
iterable (typing.Iterable): The iterable to wrap.
length (int, optional): The length of the desired progress bar.
Yields:
object: Elements from the iterable.
"""
iterable, counter = itertools.tee(iter(iterable), 2)
total = sum(1 for _ in counter)
for cur, item in enumerate(iterable):
print(f'\033[0;0H'
f'\n|{"█" * (length * (cur+1)//total)}{" " * (length - (length * (cur+1)//total))}|'
f' {100 * (cur+1)//total:3}%\n')
yield item
最便宜的选择是使用os.system('cls')来刷新整个控制台,但这相当(非常)慢,再增加40-50%的脚本运行时间(与使用相比) colorama
或只是一遍又一遍地打印。
在像ConEmu这样的替代控制台上,colorama
方法可以实现奇迹,但脚本需要打包并在多台计算机上运行,因此输出需要在Windows 7上运行的控制台上可读。
当我尝试在win7 cmd
或PowerShell
上使用colorama时出现问题,
两者都以相同的方式运行,它们并不真正识别转义序列,我输出如下:
←[0;0H
|█████████ | 9%
←[0;0H
|█████████ | 9%
←[0;0H
|█████████ | 9%
←[0;0H
|█████████ | 9%
←[0;0H
|██████████ | 10%
←[0;0H
|██████████ | 10%
如果我使用\033[0;0H
,\033[1;1H
或\033[H
,也会发生同样的情况。
我读到我以某种方式需要启用ansi.sys
(或类似的东西),但我找不到任何进一步的内容。
我的问题是......
colorama
工作?(要启用ansi.sys
代码可能吗?)cls
那么慢?其他库(如Click或Clint)是一个选项,因为项目将在分发之前通过pyinstaller
冻结,因此会自动包含任何依赖项(如果不是,则可以显式包含它们)。