我在用着tqdm
在 Python 中显示脚本中的控制台进度条。
但是,我必须调用函数print
消息也发送到控制台,我无法更改。
一般来说,在控制台中显示进度条时写入控制台会弄乱显示,如下所示:
from time import sleep
from tqdm import tqdm
def blabla():
print "Foo blabla"
for k in tqdm(range(3)):
blabla()
sleep(.5)
这将创建输出:
0%| | 0/3 [00:00<?, ?it/s]Foo
blabla
33%|###########6 | 1/3 [00:00<00:01, 2.00it/s]Foo
blabla
67%|#######################3 | 2/3 [00:01<00:00, 2.00it/s]Foo
blabla
100%|###################################| 3/3 [00:01<00:00, 2.00it/s]
根据文档tqdm https://github.com/tqdm/tqdm#writing-messages方法tqdm.write()
提供了一种将消息写入控制台而不破坏显示的进度条的方法。
因此,此代码片段提供了正确的输出:
from time import sleep
from tqdm import tqdm
def blabla():
tqdm.write("Foo blabla")
for k in tqdm(range(3)):
blabla()
sleep(.5)
看起来像这样:
Foo blabla
Foo blabla
Foo blabla
100%|###################################| 3/3 [00:01<00:00, 1.99it/s]
另一方面,还有这个允许静默这些功能的解决方案 https://stackoverflow.com/a/2829036/3434933通过相当优雅地重定向sys.stdout
进入虚空。
这对于使函数静音非常有效。
由于我想在不破坏进度条的情况下显示来自这些函数的消息,因此我尝试通过重定向将这两种解决方案合并为一个sys.stdout
to tqdm.write()
反过来,让tqdm.write()
写信给old sys.stdout
。
结果是片段:
from time import sleep
import contextlib
import sys
from tqdm import tqdm
class DummyFile(object):
file = None
def __init__(self, file):
self.file = file
def write(self, x):
tqdm.write(x, file=self.file)
@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = DummyFile(save_stdout)
yield
sys.stdout = save_stdout
def blabla():
print "Foo blabla"
for k in tqdm(range(3)):
with nostdout():
blabla()
sleep(.5)
然而,这实际上会像以前一样产生更加混乱的输出:
0%| | 0/3 [00:00<?, ?it/s]Foo
blabla
33%|###########6 | 1/3 [00:00<00:01, 2.00it/s]Foo
blabla
67%|#######################3 | 2/3 [00:01<00:00, 2.00it/s]Foo
blabla
100%|###################################| 3/3 [00:01<00:00, 2.00it/s]
仅供参考:打电话tqdm.write(..., end="")
inside DummyFile.write()
创建与第一个输出相同的结果,但仍然混乱。
我不明白为什么这行不通,因为tqdm.write()
应该在写入消息之前管理清除进度条,然后重写进度条。
我缺少什么?