Я использую tqdm
в Python для отображения консольных баров в наших скриптах. Тем не менее, мне нужно вызвать функции, которые print
сообщения на консоль также и которые я не могу изменить. В общем, писать на консоль во время отображения прогресса баров в консоли путает дисплей следующим образом:Передать команду печати в скрипте python через tqdm.write()
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]
According to the documentation of tqdm
метод tqdm.write()
предоставляет средства для записи сообщения на консоль, не нарушая отображаемые панели progressbars. Таким образом, правый выход обеспечивается посредством этого фрагмента:
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]
С другой стороны, это solution which permits to silence those functions по вполне элегантно перенаправлять sys.stdout
в пустоту. Это прекрасно работает для глушения функций.
Так как я хочу, чтобы отобразить сообщения из этих функций, тем не менее, не нарушая бары прогресса, я попытался объединить оба решения в один пути перенаправления sys.stdout
к tqdm.write()
и, в свою очередь, давая tqdm.write()
записи в старого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()
должен управлять очисткой индикатора выполнения перед записью сообщения, а затем переписывать индикатор выполнения.
Что мне не хватает?
Если 'BlaBla()' рейз ошибка, стандартный stdout никогда не будет восстановлен. – Conchylicultor