How can I flush the output of the print function (unbuffer python output)?
Solution 1
In Python 3, print
can take an optional flush
argument:
print("Hello, World!", flush=True)
In Python 2 you'll have to do
import sys
sys.stdout.flush()
after calling print
. By default, print
prints to sys.stdout
(see the documentation for more about file objects).
Solution 2
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 documentation.
Solution 3
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.
Solution 4
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.
Solution 5
Also, as suggested in this blog post, 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.
Walter Nissen
Apparently, I'm looking for a free T-shirt so I'm #SOreadytohelp
Updated on July 08, 2022Comments
-
Walter Nissen almost 2 years
How do I force Python's
print
function to output to the screen? -
gecco over 11 yearsNo vote because this IS @Dan's solution... (You should rather comment Dan's post instead of copying his solution)
-
diedthreetimes about 11 yearsI recommend not inheriting from file and then delegating to stdout by adding.
def __getattr__(self,name): return object.__getattribute__(self.f, name)
-
Colin D Bennett almost 10 yearsSuperior solution. And it works. Tested on Python 3.4.0. With the other versions, which derive from
file
, I get an error. There is nofile
class. -
blueFast about 9 yearsWithout the changes suggested by the comment by @diedthreetimes, I get "ValueError: I/O operation on closed file"
-
drevicko almost 9 yearsOn Ubuntu 12.04 in python 2.7 this gives me
UnsupportedOperation: IOStream has no fileno.
-
EKons about 8 yearsWhoops, Python 3 found out. It won't let me execute this piece of code!
-
Semicolons and Duct Tape about 8 yearsthis answer seems a little light given all the other high quality responses. you may want to add a little more to it.
-
Don Hatch over 5 yearsI'm confused by this idiom. After you do this, aren't there now two File-like objects (the original sys.stdout and the new sys.stdout) that both think they "own" the fileno? That's bad, right?
-
Oliver over 4 yearsFor the curious migrating from lower Python versions: the
__future__
version doesn't includeflush
because "the flush argument was added in Python 3.3 (after print() was backported to 2.7 via a future import)" bugs.python.org/issue28458 -
James Stevens almost 4 yearsIf you're running it on Linux/Unix platform, you can add the
-u
in the interpreter command line (first line of the script file), so change the first line from (something like)#!/usr/bin/python3
to#!/usr/bin/python3 -u
- now when you run your script (e.g../my_script.py
) the-u
will always be added for you -
TheTechRobo Stands for Ukraine over 3 yearsThis should be the accepted answer. Provides workarounds and plenty of information.
-
Charlie Parker about 3 yearsif I do
sys.stdout.flush()
can I avoid putting the flush key word? I have many prints in my file and don't want to change them + I want my files to always flush and I don't want to write it ever. Just always flush is what I want. Will puttingsys.stdout.flush()
that at the top be enough? (I am using python 3 and above) -
Charlie Parker about 3 yearsif I do
sys.stdout.flush()
can I avoid putting the flush key word? I have many prints in my file and don't want to change them + I want my files to always flush and I don't want to write it ever. Just always flush is what I want. Will puttingsys.stdout.flush()
that at the top be enough? (I am using python 3 and above) -
Charlie Parker about 3 yearsif I do
sys.stdout.flush()
can I avoid putting the flush key word? I have many prints in my file and don't want to change them + I want my files to always flush and I don't want to write it ever. Just always flush is what I want. Will puttingsys.stdout.flush()
that at the top be enough? (I am using python 3 and above) -
Russia Must Remove Putin about 3 yearsNo, but you can do something like
import functools; print = functools.partial(print, flush=True)
at the top of your module (e.g. after the imports) and even assign it to the nameprint
atbuiltins.print
for process-wide applicability. -
Charlie Parker about 3 yearslike
import functools; print2 = functools.partial(print, flush=True); builtins.print=print2
? @AaronHall -
Peter Mortensen about 3 yearsAn explanation would be in order. E.g., how is it different from Eugene Sajine's answer?
-
Peter Mortensen about 3 yearsHow is it different from Eugene Sajine's answer?
-
erobertc about 3 yearsNo, you would need to do
sys.stdout.flush()
(or useprint(..., flush=True)
in Python 3) every time you callprint
. Check this answer for another solution that might work for you. -
kristianp over 2 years
sys.stdout.flush()
works with Python 3 too. -
Charlie Parker over 2 yearsis there a command one can give to the command line to force flush?
-
Charlie Parker over 2 yearsbtw does
import sys sys.stdout.flush()
work for python3 still? I'd rather not have to modify my entire scripts to force flush. -
Charlie Parker over 2 yearsbtw does
import sys sys.stdout.flush()
work for python3 still? I'd rather not have to modify my entire scripts to force flush. -
Charlie Parker over 2 yearsbtw does
import sys sys.stdout.flush()
work for python3 still? I'd rather not have to modify my entire scripts to force flush. -
Charlie Parker over 2 years
python -u <script.py>
worked for me without having to modify script. -
N4ppeL over 2 yearsif you check de docs, buffering=0 only works in binary mode.
buffering is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line buffering (only usable in text mode), and an integer > 1 to indicate the size in bytes of a fixed-size chunk buffer.
-
Nephanth over 2 yearsprobably very late, but if you want your prints to always flush like @Charlie Parker, you could use
print = functools.partial(print, flush=True)
-
Charlie Parker over 2 yearsisn't
python -u <script.py>
best since it doesn't need you to change your code? -
SethMMorton over 2 years@PeterMortensen this answer has potty humor, the other does not.
-
Pall Arpad about 2 yearspython v3.3 supports
print(..., flush=True)