Я использую tqdm
в Python для отображения консоли-progressbars в наших скриптах.
Тем не менее, я должен вызывать функции, которые 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
метод 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]
С другой стороны, существует это решение, которое позволяет отключить эти функции, довольно элегантно перенаправляя sys.stdout
в пустоту.
Это отлично работает для глушения функций.
Так как я хочу показывать сообщения из этих функций, не нарушая индикаторы выполнения, я попытался объединить оба решения в одно, перенаправив sys.stdout
в 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]
FYI: вызов tqdm.write(..., end="")
внутри DummyFile.write()
создает тот же результат, что и первый вывод, который все еще запутан.
Я не понимаю, почему это не сработает, так как tqdm.write()
должен управлять очисткой индикатора выполнения перед записью сообщения, а затем переписывать индикатор выполнения.
Что мне не хватает?