The difference between sys.stdout.write and print?
Asked Answered
P

16

515

Are there situations in which sys.stdout.write() is preferable to print?

(Examples: better performance; code that makes more sense)

Pyrophoric answered 16/7, 2010 at 9:53 Comment(3)
Which version of Python? 2.x or 3.x?Infestation
Honestly I'd like to know for both, although I have no experience with Python 3. Updated the question.Pyrophoric
@S.Lott : asking for the basic differences between sys.stdout.write() and print (and/or why Python has both) is a perfectly reasonable question and does not need examples. OP did not say the command syntax was confusing.Does
M
367

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
Madancy answered 16/7, 2010 at 10:6 Comment(9)
It's also worth noting that print also appends a newline to whatever you write which doesn't happen with sys.stdout.write.Macguiness
@Michael Mior: True, I've said that "it formats the inputs". Better answser would mention what kind of formatting. Thanks for clarification.Madancy
Also sys.stdout.write is more universal if you ever need to write dual-version code (e.g. code that works simultaneously with Python 2.x as well as Python 3.x).Mezereon
@MichaelMior You can suppress the newline that print appends with a trailing comma: print "this",; print "on the same line as this"Epizoon
what do you mean by the fucntion is not called? " #doesn't print anything. The func is not called"Ledet
What's with the >>, or __rshift__, operator?Subsistent
@bjd2385 The >> is not the rshift operator here but a specific "chevron" form of the print statement. See docs.python.org/2/reference/…Madancy
sys.stdout.write() also buffers the input and might not flush the input to the fd immediately. in order to make sure that it behaves like the print function, you should add: sys.stdout.flush()Genetic
You can use print(blah, end="") to prevent a newline in print.Novosibirsk
P
188

print first converts the object to a string (if it is not already a string). It will also put a space before the object if it is not the start of a line and a newline character at the end.

When using stdout, you need to convert the object to a string yourself (by calling "str", for example) and there is no newline character.

So

print 99

is equivalent to:

import sys
sys.stdout.write(str(99) + '\n')
Pteryla answered 16/7, 2010 at 10:3 Comment(4)
+1 for mentioning the newline character! This is the main difference between print and .write(), I'd say.Eggbeater
NOTE: print can be made to omit the newline. In Python 2.x, put a comma at the end, and a space character will be output, but no newline. E.g. print 99, In Python 3, print(..., end='') will avoid adding newline (and also avoid adding space, unless you do end=' '.Brahmi
that's NOT true, print operation behaves slightly different in signal handlers in python2.X, i.e. print can not be replaced with sys.stdout in example: #10778110Did
for better performance let's say print(99) is equivalent to:sys.stdout.write(str(99));sys.stdout.write('\n')Dalia
P
52

Here's some sample code based on the book Learning Python by Mark Lutz that addresses your question:

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive prompt
print("another line")             # again nothing appears. it's written to log file instead
sys.stdout.close()                # ordinary file object
sys.stdout = temp                 # restore print commands to interactive prompt
print("back to normal")           # this shows up in the interactive prompt

Opening log.txt in a text editor will reveal the following:

testing123
another line
Piselli answered 29/8, 2012 at 16:43 Comment(2)
Is there any way so that I can print to screen as well as write to the file?Devoirs
@DeveshSaini: Yes, just overwrite sys.stdout with a proxy class that has at least a write() and flush() function. I wrote an example snippet here.Estaminet
C
41

My question is whether or not there are situations in which sys.stdout.write() is preferable to print

After finishing developing a script the other day, I uploaded it to a unix server. All my debug messages used print statements, and these do not appear on a server log.

This is a case where you may need sys.stdout.write instead.

Chaffer answered 16/7, 2010 at 10:59 Comment(5)
huh? Are you sure this is a difference between print() and sys.stdout.write(), as opposed to the difference between stdout and stderr? For debugging, you should use the logging module, which prints messages to stderr.Mahla
Ya. Same is true with using nohup and redirecting to a .out file.Sladen
use of sys.stdout.flush() would help.Crassus
If you use nohup, by default all writing to stdout and stderr will be re-directed to nohup.out, disregarding whether you use print or stdout.write.Legman
This answer is speculation and misleading/wrong, definitely should not have 40+ upvotes (as of this writing).Ence
R
18

There's at least one situation in which you want sys.stdout instead of print.

When you want to overwrite a line without going to the next line, for instance while drawing a progress bar or a status message, you need to loop over something like

Note carriage return-> "\rMy Status Message: %s" % progress

And since print adds a newline, you are better off using sys.stdout.

Rie answered 31/8, 2016 at 15:24 Comment(1)
If print adds a new line why not just do print('message', end = '') instead?Zoi
I
9

My question is whether or not there are situations in which sys.stdout.write() is preferable to print

If you're writing a command line application that can write to both files and stdout then it is handy. You can do things like:

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

It does mean you can't use the with open(outfile, 'w') as out: pattern, but sometimes it is worth it.

Ignaz answered 7/7, 2013 at 20:40 Comment(1)
Strictly speaking, you can use with -- def process(output): # ... / if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out) (adding newlines where necessary of course). It's definitely not very clean, though, that's for sure.Doggy
F
6

In Python 2.x, the print statement preprocesses what you give it, turning it into strings along the way, handling separators and newlines, and allowing redirection to a file. Python 3.x turns it into a function, but it still has the same responsibilities.

sys.stdout is a file or file-like class that has methods for writing to it which take strings or something along that line.

Flossieflossy answered 16/7, 2010 at 9:59 Comment(0)
C
5

It is preferable when dynamic printing is useful, for instance, to give information in a long process:

import time, sys
Iterations = 555
for k in range(Iterations+1):

    # Some code to execute here ...

    percentage = k / Iterations
    time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
    sys.stdout.write(time_msg)
    sys.stdout.flush()
    time.sleep(0.01)
Christogram answered 25/10, 2018 at 21:21 Comment(1)
print(time_msg, end='') instead sys.stdout.write(time_msg) sys.stdout.flush() also worksMalvie
G
5

A difference between print and sys.stdout.write to point out in Python 3, is also the value which is returned when executed in the terminal. In Python 3, sys.stdout.write returns the length of the string whereas print returns just None.

So for example running following code interactively in the terminal would print out the string followed by its length, since the length is returned and output when run interactively:

>>> sys.stdout.write(" hi ")
 hi 4
Glossography answered 6/3, 2020 at 18:1 Comment(0)
B
3
>>> sys.stdout.write(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a") ; print(1)
a1

Observing the example above:

  1. sys.stdout.write won't write non-string object, but print will

  2. sys.stdout.write won't add a new line symbol in the end, but print will

If we dive deeply,

sys.stdout is a file object which can be used for the output of print()

if file argument of print() is not specified, sys.stdout will be used

Beget answered 18/7, 2019 at 17:13 Comment(0)
S
2

Are there situations in which sys.stdout.write() is preferable to print?

I have found that stdout works better than print in a multithreading situation. I use a queue (FIFO) to store the lines to print and I hold all threads before the print line until my print queue is empty. Even so, using print I sometimes lose the final \n on the debug I/O (using the Wing Pro IDE).

When I use std.out with \n in the string, the debug I/O formats correctly and the \n's are accurately displayed.

Semi answered 4/9, 2018 at 7:45 Comment(3)
Do you know any reason why stdout should work better than print in this case, or is this anecdotal? Could you provide a minimal working example where this happens?Gwenngwenneth
My thinking is that stdout works at a lower level than print. I definitely had thread corruption as two print routines were fighting to feed through stdout. Writing to stdout one from each thread removed the corruption for me.Semi
#7878350Alphonsoalphonsus
O
2

In Python 3 there is valid reason to use print over sys.stdout.write, but this reason can also be turned into a reason to use sys.stdout.write instead.

This reason is that, now print is a function in Python 3, you can override this. So you can use print everywhere in a simple script and decide those print statements need to write to stderr instead. You can now just redefine the print function, you could even change the print function global by changing it using the builtins module. Off course with file.write you can specify what file is, but with overwriting print you can also redefine the line separator, or argument separator.

The other way around is. Maybe you are absolutely certain you write to stdout, but also know you are going to change print to something else, you can decide to use sys.stdout.write, and use print for error log or something else.

So, what you use depends on how you intend to use it. print is more flexible, but that can be a reason to use and to not use it. I would still opt for flexibility instead, and choose print. Another reason to use print instead is familiarity. More people will now what you mean by print and less know sys.stdout.write.

Ogilvy answered 25/10, 2018 at 11:23 Comment(0)
U
2

In Python 2, if you need to pass around a function, then you can assign os.sys.stdout.write to a variable. You cannot do this (in the REPL) with print.

>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>>

That works as expected.

>>> cmd=print
  File "<stdin>", line 1
    cmd=print
            ^
SyntaxError: invalid syntax

That does not work. print is a magical function.

Unintentional answered 23/1, 2020 at 17:25 Comment(0)
R
2

You asked,

What is the difference between sys.stdout.write and print?`

The best way I know how to explain it is to show you how to write print in terms of sys.stdout

Below I have provided three different ways to implement python's print function:

Implementation 1

import sys

def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
    # implementation One
    file.write(sep.join(str(arg) for arg in args))
    file.write(end)

Implementation 2

def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
    # Implementation 2    
    file.write(str(args[0]))
    for arg in args[1:]:
        file.write(sep)
        file.write(str(arg))
    file.write(end)
    return

Implementation 3

def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
    # implementation 3 
    it = iter(args)
    arg = next(it)
    file.write(str(arg))
    try:
        while True:
            arg = next(it)
            file.write(sep)
            file.write(str(arg))
    except StopIteration:
        pass
    file.write(end)
    return None
Rochellerochemont answered 17/9, 2022 at 2:59 Comment(0)
E
1

Are there situations in which sys.stdout.write() is preferable to print?

For example I'm working on small function which prints stars in pyramid format upon passing the number as argument, although you can accomplish this using end="" to print in a separate line, I used sys.stdout.write in co-ordination with print to make this work. To elaborate on this stdout.write prints in the same line where as print always prints its contents in a separate line.

import sys

def printstars(count):

    if count >= 1:
        i = 1
        while (i <= count):
            x=0
            while(x<i):
                sys.stdout.write('*')
                x = x+1
            print('')
            i=i+1

printstars(5)
Earphone answered 23/8, 2017 at 11:1 Comment(0)
D
1

One of the differences is the following, when trying to print a byte into its hexadecimal appearance. For example, we know that the decimal value of 255 is 0xFF in hexadecimal appearance:

val = '{:02x}'.format(255)

sys.stdout.write(val) # Prints ff2
print(val)            # Prints ff
Dismissal answered 28/9, 2019 at 15:3 Comment(1)
That's not what this is about. It would only happen in an interactive shell and because... write() did not add \n and returns (and interactive shell displays) function's return value (number of characters written), hexadecimal representation or any other content being displayed is immaterial.Agrarian

© 2022 - 2024 — McMap. All rights reserved.