I use tqdm in Python to display console-progressbars in our scripts. However, I have to call functions that print messages to the console as well and which I cannot change. In general, writing to the console while displaying progress indicators in the console causes a mess on the display as follows:
from time import sleep from tqdm import tqdm def blabla(): print "Foo blabla" for k in tqdm(range(3)): blabla() sleep(.5)
This produces a conclusion:
0%| | 0/3 [00:00<?, ?it/s]Foo blabla 33%|
According to the tqdm documentation tqdm the tqdm.write() method provides a means for writing messages to the console without violating the displayed control bars. Thus, the correct output is provided by this fragment:
from time import sleep from tqdm import tqdm def blabla(): tqdm.write("Foo blabla") for k in tqdm(range(3)): blabla() sleep(.5)
And it looks like this:
Foo blabla Foo blabla Foo blabla 100%|
On the other hand, there is a solution that allows you to disable these functions , pretty elegantly redirecting sys.stdout to void. This works great for jamming features.
Since I want to display messages from these functions without violating the progress indicators, I tried to combine both solutions into one by redirecting sys.stdout to tqdm.write() and, in turn, allowing tqdm.write() to be written to old sys.stdout The result is a fragment:
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)
However, this actually creates an even more confusing conclusion, as before:
0%| | 0/3 [00:00<?, ?it/s]Foo blabla 33%|
FYI: calling tqdm.write(..., end="") inside DummyFile.write() produces the same result as the first output, which is still confused.
I donโt understand why this will not work, since tqdm.write() must control the clearing of the progress bar before recording the message, and then rewrite the progress bar.
What am I missing?