[python] How to flush output of print function?

How do I force Python's print function to output to the screen?

This is not a duplicate of Disable output buffering - the linked question is attempting unbuffered output, while this is more general. The top answers in that question are too powerful or involved for this one (they're not good answers for this), and this question can be found on Google by a relative newbie.

This question is related to python python-3.x printing flush

The answer is


Running python -h, I see a command line option:

-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x see man page for details on internal buffering relating to '-u'

Here is the relevant doc.


Using the -u command-line switch works, but it is a little bit clumsy. It would mean that the program would potentially behave incorrectly if the user invoked the script without the -u option. I usually use a custom stdout, like this:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Now all your print calls (which use sys.stdout implicitly), will be automatically flushed.


I first struggled to understand how the flush option was working. I wanted to do a 'loading display' and here is the solution I found:

for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')

The first line flushes the previous print and the second line prints a new updated message. I don't know if an one-line syntax exists here.


Here is my version, which provides writelines() and fileno(), too:

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()

In Python 3 you can overwrite print function with default set to flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)

Using the -u command-line switch works, but it is a little bit clumsy. It would mean that the program would potentially behave incorrectly if the user invoked the script without the -u option. I usually use a custom stdout, like this:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Now all your print calls (which use sys.stdout implicitly), will be automatically flushed.


I first struggled to understand how the flush option was working. I wanted to do a 'loading display' and here is the solution I found:

for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')

The first line flushes the previous print and the second line prints a new updated message. I don't know if an one-line syntax exists here.


Dan's idea doesn't quite work:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

The result:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

I believe the problem is that it inherits from the file class, which actually isn't necessary. According to the docs for sys.stdout:

stdout and stderr needn’t be built-in file objects: any object is acceptable as long as it has a write() method that takes a string argument.

so changing

class flushfile(file):

to

class flushfile(object):

makes it work just fine.


Since Python 3.3, you can force the normal print() function to flush without the need to use sys.stdout.flush(); just set the "flush" keyword argument to true. From the documentation:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Print objects to the stream file, separated by sep and followed by end. sep, end and file, if present, must be given as keyword arguments.

All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.

The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Whether output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed.


How to flush output of Python print?

I suggest five ways of doing this:

  • In Python 3, call print(..., flush=True) (the flush argument is not available in Python 2's print function, and there is no analogue for the print statement).
  • Call file.flush() on the output file (we can wrap python 2's print function to do this), for example, sys.stdout
  • apply this to every print function call in the module with a partial function,
    print = partial(print, flush=True) applied to the module global.
  • apply this to the process with a flag (-u) passed to the interpreter command
  • apply this to every python process in your environment with PYTHONUNBUFFERED=TRUE (and unset the variable to undo this).

Python 3.3+

Using Python 3.3 or higher, you can just provide flush=True as a keyword argument to the print function:

print('foo', flush=True) 

Python 2 (or < 3.3)

They did not backport the flush argument to Python 2.7 So if you're using Python 2 (or less than 3.3), and want code that's compatible with both 2 and 3, may I suggest the following compatibility code. (Note the __future__ import must be at/very "near the top of your module"):

from __future__ import print_function
import sys

if sys.version_info[:2] < (3, 3):
    old_print = print
    def print(*args, **kwargs):
        flush = kwargs.pop('flush', False)
        old_print(*args, **kwargs)
        if flush:
            file = kwargs.get('file', sys.stdout)
            # Why might file=None? IDK, but it works for print(i, file=None)
            file.flush() if file is not None else sys.stdout.flush()

The above compatibility code will cover most uses, but for a much more thorough treatment, see the six module.

Alternatively, you can just call file.flush() after printing, for example, with the print statement in Python 2:

import sys
print 'delayed output'
sys.stdout.flush()

Changing the default in one module to flush=True

You can change the default for the print function by using functools.partial on the global scope of a module:

import functools
print = functools.partial(print, flush=True)

if you look at our new partial function, at least in Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

We can see it works just like normal:

>>> print('foo')
foo

And we can actually override the new default:

>>> print('foo', flush=False)
foo

Note again, this only changes the current global scope, because the print name on the current global scope will overshadow the builtin print function (or unreference the compatibility function, if using one in Python 2, in that current global scope).

If you want to do this inside a function instead of on a module's global scope, you should give it a different name, e.g.:

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

If you declare it a global in a function, you're changing it on the module's global namespace, so you should just put it in the global namespace, unless that specific behavior is exactly what you want.

Changing the default for the process

I think the best option here is to use the -u flag to get unbuffered output.

$ python -u script.py

or

$ python -um package.module

From the docs:

Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.

Note that there is internal buffering in file.readlines() and File Objects (for line in sys.stdin) which is not influenced by this option. To work around this, you will want to use file.readline() inside a while 1: loop.

Changing the default for the shell operating environment

You can get this behavior for all python processes in the environment or environments that inherit from the environment if you set the environment variable to a nonempty string:

e.g., in Linux or OSX:

$ export PYTHONUNBUFFERED=TRUE

or Windows:

C:\SET PYTHONUNBUFFERED=TRUE

from the docs:

PYTHONUNBUFFERED

If this is set to a non-empty string it is equivalent to specifying the -u option.


Addendum

Here's the help on the print function from Python 2.7.12 - note that there is no flush argument:

>>> from __future__ import print_function
>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep:  string inserted between values, default a space.
    end:  string appended after the last value, default a newline.

Here is my version, which provides writelines() and fileno(), too:

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()

Using the -u command-line switch works, but it is a little bit clumsy. It would mean that the program would potentially behave incorrectly if the user invoked the script without the -u option. I usually use a custom stdout, like this:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Now all your print calls (which use sys.stdout implicitly), will be automatically flushed.


Running python -h, I see a command line option:

-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x see man page for details on internal buffering relating to '-u'

Here is the relevant doc.


Why not try using an unbuffered file?

f = open('xyz.log', 'a', 0)

OR

sys.stdout = open('out.log', 'a', 0)

I did it like this in Python 3.4:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')

With Python 3.x the print() function has been extended:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

So, you can just do:

print("Visiting toilet", flush=True)

Python Docs Entry


Running python -h, I see a command line option:

-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x see man page for details on internal buffering relating to '-u'

Here is the relevant doc.


Also as suggested in this blog one can reopen sys.stdout in unbuffered mode:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Each stdout.write and print operation will be automatically flushed afterwards.


In Python 3 you can overwrite print function with default set to flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)

How to flush output of Python print?

I suggest five ways of doing this:

  • In Python 3, call print(..., flush=True) (the flush argument is not available in Python 2's print function, and there is no analogue for the print statement).
  • Call file.flush() on the output file (we can wrap python 2's print function to do this), for example, sys.stdout
  • apply this to every print function call in the module with a partial function,
    print = partial(print, flush=True) applied to the module global.
  • apply this to the process with a flag (-u) passed to the interpreter command
  • apply this to every python process in your environment with PYTHONUNBUFFERED=TRUE (and unset the variable to undo this).

Python 3.3+

Using Python 3.3 or higher, you can just provide flush=True as a keyword argument to the print function:

print('foo', flush=True) 

Python 2 (or < 3.3)

They did not backport the flush argument to Python 2.7 So if you're using Python 2 (or less than 3.3), and want code that's compatible with both 2 and 3, may I suggest the following compatibility code. (Note the __future__ import must be at/very "near the top of your module"):

from __future__ import print_function
import sys

if sys.version_info[:2] < (3, 3):
    old_print = print
    def print(*args, **kwargs):
        flush = kwargs.pop('flush', False)
        old_print(*args, **kwargs)
        if flush:
            file = kwargs.get('file', sys.stdout)
            # Why might file=None? IDK, but it works for print(i, file=None)
            file.flush() if file is not None else sys.stdout.flush()

The above compatibility code will cover most uses, but for a much more thorough treatment, see the six module.

Alternatively, you can just call file.flush() after printing, for example, with the print statement in Python 2:

import sys
print 'delayed output'
sys.stdout.flush()

Changing the default in one module to flush=True

You can change the default for the print function by using functools.partial on the global scope of a module:

import functools
print = functools.partial(print, flush=True)

if you look at our new partial function, at least in Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

We can see it works just like normal:

>>> print('foo')
foo

And we can actually override the new default:

>>> print('foo', flush=False)
foo

Note again, this only changes the current global scope, because the print name on the current global scope will overshadow the builtin print function (or unreference the compatibility function, if using one in Python 2, in that current global scope).

If you want to do this inside a function instead of on a module's global scope, you should give it a different name, e.g.:

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

If you declare it a global in a function, you're changing it on the module's global namespace, so you should just put it in the global namespace, unless that specific behavior is exactly what you want.

Changing the default for the process

I think the best option here is to use the -u flag to get unbuffered output.

$ python -u script.py

or

$ python -um package.module

From the docs:

Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode.

Note that there is internal buffering in file.readlines() and File Objects (for line in sys.stdin) which is not influenced by this option. To work around this, you will want to use file.readline() inside a while 1: loop.

Changing the default for the shell operating environment

You can get this behavior for all python processes in the environment or environments that inherit from the environment if you set the environment variable to a nonempty string:

e.g., in Linux or OSX:

$ export PYTHONUNBUFFERED=TRUE

or Windows:

C:\SET PYTHONUNBUFFERED=TRUE

from the docs:

PYTHONUNBUFFERED

If this is set to a non-empty string it is equivalent to specifying the -u option.


Addendum

Here's the help on the print function from Python 2.7.12 - note that there is no flush argument:

>>> from __future__ import print_function
>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep:  string inserted between values, default a space.
    end:  string appended after the last value, default a newline.

Running python -h, I see a command line option:

-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x see man page for details on internal buffering relating to '-u'

Here is the relevant doc.


With Python 3.x the print() function has been extended:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

So, you can just do:

print("Visiting toilet", flush=True)

Python Docs Entry


Also as suggested in this blog one can reopen sys.stdout in unbuffered mode:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Each stdout.write and print operation will be automatically flushed afterwards.


Using the -u command-line switch works, but it is a little bit clumsy. It would mean that the program would potentially behave incorrectly if the user invoked the script without the -u option. I usually use a custom stdout, like this:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Now all your print calls (which use sys.stdout implicitly), will be automatically flushed.


Dan's idea doesn't quite work:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

The result:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

I believe the problem is that it inherits from the file class, which actually isn't necessary. According to the docs for sys.stdout:

stdout and stderr needn’t be built-in file objects: any object is acceptable as long as it has a write() method that takes a string argument.

so changing

class flushfile(file):

to

class flushfile(object):

makes it work just fine.


Dan's idea doesn't quite work:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

The result:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

I believe the problem is that it inherits from the file class, which actually isn't necessary. According to the docs for sys.stdout:

stdout and stderr needn’t be built-in file objects: any object is acceptable as long as it has a write() method that takes a string argument.

so changing

class flushfile(file):

to

class flushfile(object):

makes it work just fine.


Since Python 3.3, you can force the normal print() function to flush without the need to use sys.stdout.flush(); just set the "flush" keyword argument to true. From the documentation:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Print objects to the stream file, separated by sep and followed by end. sep, end and file, if present, must be given as keyword arguments.

All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.

The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Whether output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed.


Why not try using an unbuffered file?

f = open('xyz.log', 'a', 0)

OR

sys.stdout = open('out.log', 'a', 0)

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to python-3.x

Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation Replace specific text with a redacted version using Python Upgrade to python 3.8 using conda "Permission Denied" trying to run Python on Windows 10 Python: 'ModuleNotFoundError' when trying to import module from imported package What is the meaning of "Failed building wheel for X" in pip install? How to downgrade python from 3.7 to 3.6 I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? Iterating over arrays in Python 3 How to upgrade Python version to 3.7?

Examples related to printing

How do I print colored output with Python 3? Print a div content using Jquery Python 3 print without parenthesis How to find integer array size in java Differences Between vbLf, vbCrLf & vbCr Constants Printing variables in Python 3.4 Show DataFrame as table in iPython Notebook Removing display of row names from data frame Javascript window.print() in chrome, closing new window or tab instead of cancelling print leaves javascript blocked in parent window Print a div using javascript in angularJS single page application

Examples related to flush

How often does python flush to a file? How to flush output after each `echo` call? What is the purpose of flush() in Java streams? Why does printf not flush after the call unless a newline is in the format string? Force flushing of output to a file while bash script is still running How to flush output of print function?