27

Ipython Notebook doesn't seem to print results in real time, but seems to buffer in a certain way and then bulk output the prints. How can I make ipython print my results as soon as the print command is processed?

Example code:

import time


def printer():
    for i in range(100):
        time.sleep(5)
        print i

Supposing that the above code is in a file that is imported. How could I make it that when I call the printer function it prints a number every 5 seconds and not all the numbers at the very end?

Please note that I cannot edit the function printer() because I get it from some external module. I want the to change the configs of ipython notebook somehow so that it doesn't use a buffer. Therefore, I also do not wish to use sys.stdout.flush(), I want to do it in real-time according to the question, I don't want any buffer to start with.

I also tried loading ipython notebook with the command:

ipython notebook --cache-size=0

but that also doesn't seem to work.

6
  • Thanks. My question is slighly different. I don't want to change the function printer() because I get it though importing a module which I don't want to change. I simply want to change the behaviour of ipython. So the solutions proposed in the above question don't work for me because I can't add sys.stdout.flush() to the function. What I want is that there be no buffer in ipython notebook. That it outputs everything automatically. Commented Apr 21, 2015 at 13:48
  • 2
    You could monkeypatch the printer function. Commented Apr 21, 2015 at 13:51
  • Possibly, but there should be a way to unbuffer ipython notebook stdout no? Commented Apr 21, 2015 at 14:01
  • With the added requirement you can find some answers here Commented Apr 21, 2015 at 16:22
  • Thanks, but I couldn't really find anything that works. Commented Apr 22, 2015 at 7:59

4 Answers 4

16
+50

This is merely one of the answers to the question suggested by Carsten incorporating the __getattr__ delegation suggested by diedthreetimes in a comment:

import sys
oldsysstdout = sys.stdout
class flushfile():
    def __init__(self, f):
        self.f = f
    def __getattr__(self,name): 
        return object.__getattribute__(self.f, name)
    def write(self, x):
        self.f.write(x)
        self.f.flush()
    def flush(self):
        self.f.flush()
sys.stdout = flushfile(sys.stdout)

In the original answer, the __getattr__ method is not implemented. Without that, it fails. Other variants in answers to that question also fail in a notebook.

In a notebook, sys.stdout is an instance of IPython.kernel.zmq.iostream.OutStream and has a number of methods and attributes not present in the usual sys.stdout. Delegating __getattr__ allows a flushfile to masquerade as a ...zmq.iostream.OutStream duck.

This works in a python 2.7 notebook run with ipython 3.1.0

Sign up to request clarification or add additional context in comments.

2 Comments

It's quite a work around, but thank you! I will try it.
It works!! :) Thank you! I'll attribute the bounty in 2 days.
12

Since Python 3.3, print() has an additional flush argument that can be used to force flushing:

for i in range(10):
    print(i, flush=True)
    time.sleep(1)  

Comments

2

Try this:

from IPython.display import display, clear_output

display("Hello World") # print string
display(df) # print object such as dataframe

clear_output(wait=True) # use this if need to clear the output before display, good for dynamic updates

Comments

0

Additionally, you can use the carriage return character:

from time import sleep
for i in range(10):
    print(i, end='\r')
    sleep(1)

Or if you're using Jupyter Notebooks:

from IPython.display import clear_output
from time import sleep
for i in range(10):
    print(i)
    sleep(1)
    clear_output(wait=True) 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.