1573

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


See also: Disable output buffering if the goal is to change the buffering behaviour generally. This question is about explicitly flushing output after a specific print call, even though output is still being buffered.

For duplicate closers: if a beginner is asking a question about trying to make output appear immediately while not using a newline at the end, please instead use Why doesn't print output show up immediately in the terminal when there is no newline at the end? to close the question. The current question isn't good enough because the person asking will likely not have a concept of buffering or flushing; the other question is intended to explain those concepts first, whereas this question is about the technical details.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Walter Nissen
  • 16,451
  • 4
  • 26
  • 27
  • 11
    `python -u ` worked (forced flushed, no buffering) for me without having to modify script. – Charlie Parker Nov 10 '21 at 19:19
  • 1
    Note that the behavior is famously broken within IDEs. For example, PyCharm works correctly in the debug console, but not in the run console. You may need to isolate that the problem exists in a regular terminal. – Charles Merriam Dec 31 '21 at 23:49

13 Answers13

1855

In Python 3, print can take an optional flush argument:

print("Hello, World!", flush=True)

In Python 2, after calling print, do:

import sys
sys.stdout.flush()

By default, print prints to sys.stdout (see the documentation for more about file objects).

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
CesarB
  • 43,947
  • 7
  • 63
  • 86
  • 2
    if 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 putting `sys.stdout.flush()` that at the top be enough? (I am using python 3 and above) – Charlie Parker Apr 02 '21 at 20:01
  • 2
    No, you would need to do `sys.stdout.flush()` (or use `print(..., flush=True)` in Python 3) every time you call `print`. Check [this answer](https://stackoverflow.com/a/230780/2328207) for another solution that might work for you. – erobertc Apr 22 '21 at 00:03
  • `sys.stdout.flush()` works with Python 3 too. – kristianp Oct 31 '21 at 05:04
  • is there a command one can give to the command line to force flush? – Charlie Parker Nov 10 '21 at 19:13
  • btw 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 Nov 10 '21 at 19:15
  • 5
    `python -u ` worked for me without having to modify script. – Charlie Parker Nov 10 '21 at 19:19
  • 19
    probably very late, but if you want your prints to always flush like @Charlie Parker, you could use `print = functools.partial(print, flush=True)` – tbrugere Nov 24 '21 at 06:41
  • isn't `python -u ` best since it doesn't need you to change your code? – Charlie Parker Nov 24 '21 at 18:37
  • python v3.3 supports `print(..., flush=True)` – Pall Arpad Apr 20 '22 at 06:23
  • 1
    Sometimes python 3.8.3 on my Mac, flush=True does nothing, when the next message is a logger. I have to add sys.stdout.flush() – Eric H. Dec 15 '22 at 09:44
429

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gimel
  • 83,368
  • 10
  • 76
  • 104
  • 13
    If 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 – James Stevens Sep 07 '20 at 17:22
  • `-u` works as expected (Y) – younes zeboudj Jun 23 '23 at 11:08
341

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.

Community
  • 1
  • 1
Eugene Sajine
  • 8,104
  • 3
  • 23
  • 28
  • 1
    if 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 putting `sys.stdout.flush()` that at the top be enough? (I am using python 3 and above) – Charlie Parker Apr 02 '21 at 20:01
  • btw 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 Nov 10 '21 at 19:15
268

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.
Community
  • 1
  • 1
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • 2
    For the curious migrating from lower Python versions: the `__future__` version doesn't include `flush` because "the flush argument was added in Python 3.3 (after print() was backported to 2.7 via a future import)" https://bugs.python.org/issue28458 – Oliver Mar 18 '20 at 01:46
  • This should be the accepted answer. Provides workarounds and plenty of information. – TheTechRobo the Nerd Jan 24 '21 at 22:16
  • if 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 putting `sys.stdout.flush()` that at the top be enough? (I am using python 3 and above) – Charlie Parker Apr 02 '21 at 20:01
  • No, 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 name `print` at `builtins.print` for process-wide applicability. – Russia Must Remove Putin Apr 02 '21 at 20:52
  • like `import functools; print2 = functools.partial(print, flush=True); builtins.print=print2`? @AaronHall – Charlie Parker Apr 02 '21 at 21:10
  • btw 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 Nov 10 '21 at 19:15
71

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
  • 3
    On Ubuntu 12.04 in python 2.7 this gives me `UnsupportedOperation: IOStream has no fileno.` – drevicko Jul 01 '15 at 04:58
  • 4
    Whoops, Python 3 found out. It won't let me execute this piece of code! – EKons Apr 30 '16 at 17:43
  • 1
    I'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? – Don Hatch Oct 19 '18 at 13:41
  • if 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.``` – N4ppeL Nov 11 '21 at 15:43
70

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

Noah Krasser
  • 1,081
  • 1
  • 14
  • 22
40

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.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Dan Lenski
  • 76,929
  • 13
  • 76
  • 124
  • 5
    I recommend not inheriting from file and then delegating to stdout by adding. `def __getattr__(self,name): return object.__getattribute__(self.f, name)` – diedthreetimes Jun 23 '13 at 19:21
  • 2
    Without the changes suggested by the comment by @diedthreetimes, I get "ValueError: I/O operation on closed file" – blueFast Apr 27 '15 at 22:43
20

Use an unbuffered file:

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

Or

sys.stdout = open('out.log', 'a', 0)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 4
    He does not want ot create an unbuffered file; he wants to make the existing stdout (redirected to the console, the terminal or whatever: this must not be changed) unbuffered. – blueFast Apr 28 '15 at 12:58
18

In Python 3 you can overwrite the print function with the 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)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user263387
  • 457
  • 4
  • 5
16

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 documentation 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamil Kisiel
  • 19,723
  • 11
  • 46
  • 56
  • 20
    No vote because this IS @Dan's solution... (You should rather comment Dan's post instead of copying his solution) – gecco Jan 15 '13 at 15:30
12

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()
m45t3r
  • 477
  • 4
  • 13
guettli
  • 25,042
  • 81
  • 346
  • 663
  • 1
    Superior solution. And it works. Tested on Python 3.4.0. With the other versions, which derive from `file`, I get an error. There is no `file` class. – Colin D Bennett Sep 22 '14 at 20:58
8

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...')
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
kmario23
  • 57,311
  • 13
  • 161
  • 150
  • An explanation would be in order. E.g., how is it different from [Eugene Sajine's answer](https://stackoverflow.com/questions/230751/how-can-i-flush-the-output-of-the-print-function/23142556#23142556)? – Peter Mortensen Apr 09 '21 at 11:04
5

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.