Does `print()` delay in some consoles where `stdout.flush` doesn't?
Question:
I’m working on an open source python library that uses a verbose_print
command to log outputs in the console. Currently it looks like this:
def sys_write_flush(s):
""" Writes and flushes without delay a text in the console """
sys.stdout.write(s)
sys.stdout.flush()
def verbose_print(verbose, s):
""" Only prints s (with sys_write_flush) if verbose is True."""
if verbose:
sys_write_flush(s)
I proposed a change that looks like this:
def verbose_print(verbose, *args):
""" Prints everything passed except the first argument if verbose is True."""
if verbose:
print(*args)
Apart from the fact that it fails on Python 2 (bonus point for fixing this!), I thought that this would be better and more idiomatic. The advantages are, that you can treat verbose_print
exactly like print
, except that the first argument has to be True
or False
.
The repo owner replied with this message:
I should have documented this one, but basically the issue was that in
some consoles (and in the IPython notebook, at least at the time),
"print" commands get delayed, while stdout.flush are instantaneous, so
my method was better at providing feedback.
I would be against changing it to print unless it solves some known
issues.
Is this still a valid concern? Would print()
followed by sys.stdout.flush()
avoid the delay? Are there any better ways to write this?
Answers:
Quote from the docs:
print
evaluates each expression in turn and writes the resulting
object to standard output.
Standard output is defined as the file object named stdout
in the
built-in module sys
. If no such object exists, or if it does not
have a write()
method, a RuntimeError
exception is raised.
According to this, print
writes to sys.stdout
, so, yes, doing a sys.stdout.flush()
after print
ing will have the same effect as flush
ing after sys.stdout.write
-ing.
The syntax print(*a)
fails in Python 2 because print
isn’t a function, but a statement, and that fun(*stuff)
construct is only applicable to functions.
In Python 3 print(*a)
passes whatever a
contains to the function print
as separate arguments, but this is equal to passing a big string:
separator = ' '
print separator.join(map(str, iterable))
So, your code could look like this:
def verbose_print(verbose, *args):
""" Prints everything passed except the first argument if verbose is True."""
if verbose:
print " ".join(map(str, args))
sys.stdout.flush()
Although I don’t see why this can be faster or more readable than the original.
I’m working on an open source python library that uses a verbose_print
command to log outputs in the console. Currently it looks like this:
def sys_write_flush(s):
""" Writes and flushes without delay a text in the console """
sys.stdout.write(s)
sys.stdout.flush()
def verbose_print(verbose, s):
""" Only prints s (with sys_write_flush) if verbose is True."""
if verbose:
sys_write_flush(s)
I proposed a change that looks like this:
def verbose_print(verbose, *args):
""" Prints everything passed except the first argument if verbose is True."""
if verbose:
print(*args)
Apart from the fact that it fails on Python 2 (bonus point for fixing this!), I thought that this would be better and more idiomatic. The advantages are, that you can treat verbose_print
exactly like print
, except that the first argument has to be True
or False
.
The repo owner replied with this message:
I should have documented this one, but basically the issue was that in
some consoles (and in the IPython notebook, at least at the time),
"print" commands get delayed, while stdout.flush are instantaneous, so
my method was better at providing feedback.I would be against changing it to print unless it solves some known
issues.
Is this still a valid concern? Would print()
followed by sys.stdout.flush()
avoid the delay? Are there any better ways to write this?
Quote from the docs:
object to standard output.
Standard output is defined as the file object named
stdout
in the
built-in modulesys
. If no such object exists, or if it does not
have awrite()
method, aRuntimeError
exception is raised.
According to this, print
writes to sys.stdout
, so, yes, doing a sys.stdout.flush()
after print
ing will have the same effect as flush
ing after sys.stdout.write
-ing.
The syntax print(*a)
fails in Python 2 because print
isn’t a function, but a statement, and that fun(*stuff)
construct is only applicable to functions.
In Python 3 print(*a)
passes whatever a
contains to the function print
as separate arguments, but this is equal to passing a big string:
separator = ' '
print separator.join(map(str, iterable))
So, your code could look like this:
def verbose_print(verbose, *args):
""" Prints everything passed except the first argument if verbose is True."""
if verbose:
print " ".join(map(str, args))
sys.stdout.flush()
Although I don’t see why this can be faster or more readable than the original.