DekGenius.com
[ Team LiB ] Previous Section Next Section

8.3 Print Statements

The print statement simply prints objects. Technically, it writes the textual representation of objects to the standard output stream. The standard output stream is the same as the C language's stdout; it is usually mapped to the window where you started your Python program (unless redirected to a file in your system's shell).

In Chapter 7, we also saw file methods that write text. The print statement is similar, but more focused: print writes objects to the stdout stream (with some default formatting), but file write methods write strings to files. Since the standard output stream is available in Python as the stdout object in the built-in sys module (i.e., sys.stdout), it's possible to emulate print with file writes, but print is easier to use.

Table 8-6 lists the print statement's forms. We've seen the basic print statement in action already. By default, it adds a space between the items separated by commas, and adds a linefeed at the end of the current output line:

>>> x = 'a'
>>> y = 'b'
>>> print x, y
a b

Table 8-6. Print statement forms

Operation

Interpretation

print spam, ham

Print objects to sys.stdout; add a space between.

print spam, ham,

Same, but don't add newline at end of text.

print >> myfile, spam, ham

Send text to myfile.write, not to sys.stdout.write.

This formatting is just a default; you can choose to use it or not. To suppress the linefeed (so you can add more text to the current line later), end your print statement with a comma, as shown in the second line of Table 8-6. To suppress the space between items, you can instead build up an output string yourself using the string concatenation and formatting tools covered in Chapter 5, and print the string all at once:

>>> print x + y
ab
>>> print '%s...%s' % (x, y)
a...b

8.3.1 The Python "Hello World" Program

To print a hello world message, you simply print it:

>>> print 'hello world'                 # Print a string object.
hello world

Since expression results are echoed in the interactive command line, you often don't even need to use a print statement there; simply type expressions you'd like to have printed and their results are echoed back:

>>> 'hello world'                       # Interactive echoes
'hello world'

Really, the print statement is just an ergonomic feature of Python—it provides a user-friendly interface to the sys.stdout object, with a bit of default formatting. You can also code print operations this way:

>>> import sys                          # Printing the hard way
>>> sys.stdout.write('hello world\n')
hello world

This code explicitly calls the write method of sys.stdout—an attribute preset when Python starts up to an open file object connected to the output stream. The print statement hides most of those details. It provides a simple tool for simple printing tasks.

8.3.2 Redirecting the Output Stream

The sys.stdout print equivalent turns out to be basis of a common technique in Python. In general, print and sys.stdout are related as follows:

print X

is equivalent to the longer:

import sys
sys.stdout.write(str(X) + '\n')

that manually performs a string conversion with str, adds a newline with +, and calls the output stream's write method. The long form isn't all that useful for printing by itself. However, it is useful to know that this is exactly what print statements do, because it is possible to reassign sys.stdout to something different than the standard output stream. In other words, this equivalence provides a way for making your print statements send their text to other places. For example:

import sys
sys.stdout = open('log.txt', 'a')     # Redirects prints to file
...
print x, y, x                         # Shows up in log.txt

Here, we reset sys.stdout to a manually-opened output file object opened in append mode. After the reset, every print statement anywhere in the program will write its text to the end of file log.txt, instead of the original output stream. The print statements are happy to keep calling sys.stdout's write method, no matter what sys.stdout happens to refer to.

In fact, as this chapter's sidebar on print and stdout will explain, we can even reset sys.stdout to nonfile objects, as long as they have the expected protocol (a write method); when those objects are classes, printed text can be routed and processed arbitrarily.

Why You Will Care: print and stdout

The equivalence between the print statement and writing to sys.stdout is important to notice. It makes it possible to reassign sys.stdout to a user-defined object that provides the same methods as files (e.g., write). Since the print statement just sends text to the sys.stdout.write method, you can capture printed text in your programs by assigning sys.stdout to an object whose write method processes the text in arbitrary ways.

For instance, you can send printed text to a GUI window by defining an object with a write method that does the routing. You'll see an example of this trick later in the book, but abstractly, it looks like this:

class FileFaker:
    def write(self, string):
        # Do something with the string.
import sys
sys.stdout = FileFaker(  )
print someObjects         # Sends to the class write method

This works because print is what we will call a polymorphic operation in the next part of this book—it doesn't care what sys.sytdout is, only that it has a method (i.e., interface) called write. This redirection to objects is even simpler:

myobj = FileFaker(  )
print >> myobj, someObjects   # Does not reset sys.stdout

Python's built-in raw_input( ) function reads from the sys.stdin file, so you can intercept read requests in a similar way—using classes that implement file-like read methods. See the raw_input and while loop example in Chapter 10 for more background on this.

Notice that since print text goes to the stdout stream, it's the way to print HTML in CGI scripts. It also means you can redirect Python script input and output at the operating system's command line, as usual:

python script.py < inputfile > outputfile
python script.py | filterProgram


8.3.2.1 The print>>file extension

This trick of redirecting printed text by assigning sys.stdout was so commonly used that Python's print statement has an extension to make it easier. One potential problem with the last section's code is that there is no direct way to restore the original output stream, should you need to switch back after printing to a file. We can always save and restore as needed:[6]

[6] We can also use the relatively new __stdout__ attribute in module sys, which refers to the original value sys.stdout had at program start-up time. We still need to restore sys.stdout to sys.__stdout__ to go back to this original stream value, though. See the sys module in the library manual for more details.

import sys
temp = sys.stdout                     # Save for restoring.
sys.stdout = open('log.txt', 'a')     # Redirects prints to file
...
print x, y, x                         # Print to file.
... 
sys.stdout = temp
print a, b, c                         # Print to original stdout.

But this is just complicated enough that a print extension was added to make the save and restore unnecessary. When a print statement begins with a >> followed by an output file (or other) object, that single print statement sends its text to the object's write method, but does not reset sys.stdout. Because the redirection is temporary, normal print statements keep printing to the original output stream:

log =  open('log.txt', 'a')     
print >> log, x, y, z                 # Print to a file-like object.
print a, b, c                         # Print to original stdout.

The >> form of the print is handy if you need to print to both files and the standard output stream. If you use this form, be sure to give it a file object (or an object that has the same write method as a file object), not a file's name string.

    [ Team LiB ] Previous Section Next Section