下面是一个最小的可重现性示例:
import logging
from tqdm import tqdm
for i in tqdm(range(1000)):
for _ in range(2000):
a = i+8
if i % 100 == 0:
logging.warning("test")
这将产生以下结果:
0%| | 0/1000 [00:00<?, ?it/s]WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
100%|██████████| 1000/1000 [00:00<00:00, 996982.17it/s]
我可以再次刷新和打印条形(基本上没有参数leave=True
),但是第一个警告没有中断。它对print("test")
也不是很好
0%| | 0/1000 [00:00<?, ?it/s]test
test
test
test
test
test
test
test
test
test
100%|██████████| 1000/1000 [00:00<00:00, 20526.40it/s]
知道如何为第一次打印/日志设置适当的行间隔吗?我不能添加"\n“,因为否则,对于以下打印消息,我将有太多的换行符。并且添加一个“如果这是第一条消息,那么添加"\n”否则不“听起来像一个肮脏的方式绕过这个问题。
我看过这篇文章(tqdm with logger on separate lines),但除了“自己做自己的tqdm”之外,这不是什么答案,因为我喜欢做tqdm(my_iterable)
。
发布于 2022-11-02 07:10:15
在将输出写入stdout或stderr之前,可以通过调用tqdm
对象的tqdm
方法来清除状态栏。
要使对clear
方法的调用对每个输出自动进行,您可以创建一个上下文管理器,它用一个包装器函数对sys.stdout
和sys.stderr
进行修补,该包装函数在将消息写入原始sys.stderr
之前调用给定tqdm
对象的clear
方法。
import sys
from unittest.mock import patch
from contextlib import contextmanager
@contextmanager
def tqdm_output(tqdm, write=sys.stderr.write):
def wrapper(message):
if message != '\n':
tqdm.clear()
write(message)
if '\n' in message:
tqdm.display()
with patch('sys.stdout', sys.stderr), patch('sys.stderr.write', wrapper):
yield tqdm
这样,您就可以将迭代放在上下文管理器中,并正常使用记录器:
with tqdm_output(tqdm(range(1000))) as trange:
for i in trange:
if i % 100 == 0:
logging.warning("test")
它的输出是:
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
WARNING:root:test
100%|██████████████████████████████| 1000/1000 [00:00<00:00, 1797.66it/s]
与使用print
相同
with tqdm_output(tqdm(range(1000))) as trange:
for i in trange:
if i % 100 == 0:
print('test')
其中产出:
test
test
test
test
test
test
test
test
test
test
100%|███████████████████████████████| 1000/1000 [00:05<00:00, 181.55it/s]
https://stackoverflow.com/questions/74222161
复制相似问题