The Difference Between Sys.Stdout.Write and Print

The difference between sys.stdout.write and print?

print is just a thin wrapper that formats the inputs (modifiable, but by default with a space between args and newline at the end) and calls the write function of a given object. By default this object is sys.stdout, but you can pass a file using the "chevron" form. For example:

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

See: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


In Python 3.x, print becomes a function, but it is still possible to pass something other than sys.stdout thanks to the fileargument.

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

See https://docs.python.org/3/library/functions.html#print


In Python 2.6+, print is still a statement, but it can be used as a function with

from __future__ import print_function

Update: Bakuriu commented to point out that there is a small difference between the print function and the print statement (and more generally between a function and a statement).

In case of an error when evaluating arguments:

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The function is not called

print() vs sys.stdout.write(): which and why?

"Can someone please explain (or direct me to an existing explanation) the differences between print() and sys.stdout.write, the cases in which each should be used and the rational for those conventions?"

Well I guess the silence you hear regarding Python3's print() function, is because there practically is only one difference: Usage. Let me quote PEP-3105: [1]

The signature for print() is:

def print(*args, sep=' ', end='\n', file=None)

A call like:

print(a, b, c, file=sys.stderr)

will be equivalent to today's:

print >>sys.stderr, a, b, c

while the optional sep and end arguments specify what is printed between and after the arguments, respectively.

The softspace feature (a semi-secret attribute on files currently used to tell print whether to insert a space before the first item) will be removed. Therefore, there will not be a direct translation for today's:

print "a", print

which will not print a space between the "a" and the newline.

So, quoting Guido van Rossum's discussion of the problem in 2005 [1]: There is a distinct non-linearity in print's ease of use once you decide that you don't want to have spaces between items; you either have to switch to using sys.stdout.write(), or you have to collect all items in a string. This is not a simple transformation, consider what it takes to get rid of the spaces before the commas in this simple example:

print "x =", x, ", y =", y, ", z =", z

If it was a built-in function, having a built-in companion function that did a similar thing without inserting spaces and adding a newline would be the logical thing to do (or adding keyword parameters to control that behavior; but I prefer a second function); but with only
print as it currently stands, you'd have to switch to something like

print "x = " + str(x) + ", y = " + str(x) + ", z = " + str(z)

or

print "x = %s, y = %s, z = %s" % (x, y, z)

neither of which is very attractive. (And don't tell me that the spaces are no big deal -- they aren't in this example, but they are in other situations.)


Good question for a sunday morning down memory lane; Why this apparent redundancy? Because it is pythonically more correct to write higher-level code:

7th Zen of python: "Readability counts"

Difference between sys.stdout.write and print when printing variables

The return value for sys.stdout.write() returns the no. of bytes written. In this case 1 which also gets printed on the interactive interpret prompt for any expressions entered.

Example:

>>> import sys
>>> sys.stdout.write("foo")
foo3

If you wanted to hide this you could do this:

>>> nbytes = sys.stdout.write("foo\n")
foo

sys.stdout.write() Acting different in interactive mode

12 is the return value of write, i.e. the number of characters written. which in interactive mode is printed out, followed by a line feed

to fix this you could either indicate to the interpreter that you're not interested in this value (e.g. using _ = stdout.write(s)) or you could put everything into a function and hence keep it away from the REPL

I'd suggest doing the latter, e.g. something like:

def looper(n):
for i in range(n):
sys.stdout.write("\r Loading: {}".format(i))
sys.stdout.flush()
time.sleep(0.5)
sys.stdout.write("\n")

then invoke as looper(10)

python unicode handling differences between print and sys.stdout.write

This is due to a long-standing bug that was fixed in python-2.7, but too late to be back-ported to python-2.6.

The documentation states that when unicode strings are written to a file, they should be converted to byte strings using file.encoding. But this was not being honoured by sys.stdout, which instead was using the default unicode encoding. This is usually set to "ascii" by the site module, but it can be changed with sys.setdefaultencoding:

Python 2.6.7 (r267:88850, Aug 14 2011, 12:32:40) [GCC 4.6.2] on linux3
>>> a = u'\xa6\n'
>>> sys.stdout.write(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec cant encode character u'\xa6' ...
>>> reload(sys).setdefaultencoding('utf8')
>>> sys.stdout.write(a)
¦

However, a better solution might be to replace sys.stdout with a wrapper:

class StdOut(object):
def write(self, string):
if isinstance(string, unicode):
string = string.encode(sys.__stdout__.encoding)
sys.__stdout__.write(string)

>>> sys.stdout = StdOut()
>>> sys.stdout.write(a)
¦

Why is sys.stdout.write called twice?

Your perceived results indicates that print() calls file.write twice: Once for the data and once for the "end content", which is a newline by default and can be overridden with the end keyword argument. Relevant source code lines confirm this speculation.

However, this is not something you should rely on. It's entirely implementation details, may be different for another implementation (e.g. PyPy) and may change at any time without notice, not to mention that overriding builtins is another bad practice. You should avoid this kind of practice without a compelling reason not to modify other parts of the code to use your custom logging facility.

Should you really need to do monkey-patching, it's safer to override the print() function since it has a defined, reliable interface. You can import the builtins module and assign your new print function to builtins.print, maintaining control over calls to your logging handler.

Is there a function to print w/o newline that is not sys.stdout.write or print(,end=)?

You're using the IDLE shell to run your program, don't.

IDLE poorly manages outputting text and does slow down when outputting extremely long lines of it (this is the reason why print without the end keyword argument works alright, because you're printing multiple separate lines, not 1 line which is getting increasingly longer).

Instead just use the standard Windows command line (cmd.exe).

You can do this (assuming your installation has been configured correctly) by either running your .py file via the GUI or by running:

python filename.py

in the command line.

This has been reported as a bug in Python (IDLE shell window gets very slow when displaying long lines) back in 2006 and the issue is still open.

You can read more including some numbers on this Stack Overflow post.



Related Topics



Leave a reply



Submit