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.pythonprintingflush
import sys sys.stdout.flush()
Print by default prints to
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.
-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(object): 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
sys.stdout implicitly), will be automatically
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"
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.
makes it work just fine.
Why not try using an unbuffered file?
f = open('xyz.log', 'a', 0)
sys.stdout = open('out.log', 'a', 0)
Loved Dan's solution! For python3 do:
import io,sys class flushfile: def __init__(self, f): self.f = f def write(self, x): self.f.write(x) self.f.flush() sys.stdout = flushfile(sys.stdout)
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()
import sys print 'This will be output immediately.' sys.stdout.flush()
Also as suggested in this blog one can reopen
sys.stdout in unbuffered mode:
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
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.
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 they extended the
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
So, you can just do:
print("Visiting toilet", flush=True)
How to flush output of Python print?
I suggest five ways of doing this:
file.flush()on the output file (we can wrap python 2's print function to do this), for example,
print = partial(print, flush=True)applied to the module global.
-u) passed to the interpreter command
PYTHONUNBUFFERED=TRUE(and unset the variable to undo this).
Using Python 3.3 or higher, you can just provide
flush=True as a keyword argument to the
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
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()
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
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.
I think the best option here is to use the
-u flag to get unbuffered output.
$ python -u script.py
$ 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.
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
from the docs:
If this is set to a non-empty string it is equivalent to specifying the -u option.
Here's the help on the print function from Python 2.7.12 - note that there is no
>>> 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.
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)