Print Operations

In Python, print prints things—it’s simply a programmer-friendly interface to the standard output stream.

Technically, printing converts one or more objects to their textual representations, adds some minor formatting, and sends the resulting text to either standard output or another file-like stream. In a bit more detail, print is strongly bound up with the notions of files and streams in Python:

File object methods

In Chapter 9, we learned about file object methods that write text (e.g., file.write(str)). Printing operations are similar, but more focused—whereas file write methods write strings to arbitrary files, print writes objects to the stdout stream by default, with some automatic formatting added. Unlike with file methods, there is no need to convert objects to strings when using print operations.

Standard output stream

The standard output stream (often known as stdout) is simply a default place to send a program’s text output. Along with the standard input and error streams, it’s one of three data connections created when your script starts. The standard output stream is usually mapped to the window where you started your Python program, unless it’s been redirected to a file or pipe in your operating system’s shell.

Because the standard output stream is available in Python as the stdout file object in the built-in sys module (i.e., sys.stdout), it’s possible to emulate print with file write method calls. However, print is noticeably easier to use and makes it easy to print text to other files and streams.

Printing is also one of the most visible places where Python 3.X and 2.X have diverged. In fact, this divergence is usually the first reason that most 2.X code won’t run unchanged under 3.X. Specifically, the way you code print operations depends on which version of Python you use:

Because this book covers both 3.X and 2.X, we will look at each form in turn here. If you are fortunate enough to be able to work with code written for just one version of Python, feel free to pick the section that is relevant to you. Because your needs may change, however, it probably won’t hurt to be familiar with both cases. Moreover, users of recent Python 2.X releases can also import and use 3.X’s flavor of printing in their Pythons if desired—both for its extra functionality and to ease future migration to 3.X.

The Python 3.X print Function

Strictly speaking, printing is not a separate statement form in 3.X. Instead, it is simply an instance of the expression statement we studied in the preceding section.

The print built-in function is normally called on a line of its own, because it doesn’t return any value we care about (technically, it returns None, as we saw in the preceding section). Because it is a normal function, though, printing in 3.X uses standard function-call syntax, rather than a special statement form. And because it provides special operation modes with keyword arguments, this form is both more general and supports future enhancements better.

By comparison, Python 2.X print statements have somewhat ad hoc syntax to support extensions such as end-of-line suppression and target files. Further, the 2.X statement does not support separator specification at all; in 2.X, you wind up building strings ahead of time more often than you do in 3.X. Rather than adding yet more ad hoc syntax, Python 3.X’s print takes a single, general approach that covers them all.

Call format

Syntactically, calls to the 3.X print function have the following form (the flush argument is new as of Python 3.3):

print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout][, flush=False])

In this formal notation, items in square brackets are optional and may be omitted in a given call, and values after = give argument defaults. In English, this built-in function prints the textual representation of one or more objects separated by the string sep and followed by the string end to the stream file, flushing buffered output or not per flush.

The sep, end, file, and (in 3.3 and later) flush parts, if present, must be given as keyword arguments—that is, you must use a special “name=value” syntax to pass the arguments by name instead of position. Keyword arguments are covered in depth in Chapter 18, but they’re straightforward to use. The keyword arguments sent to this call may appear in any left-to-right order following the objects to be printed, and they control the print operation:

  • sep is a string inserted between each object’s text, which defaults to a single space if not passed; passing an empty string suppresses separators altogether.

  • end is a string added at the end of the printed text, which defaults to a \n newline character if not passed. Passing an empty string avoids dropping down to the next output line at the end of the printed text—the next print will keep adding to the end of the current output line.

  • file specifies the file, standard stream, or other file-like object to which the text will be sent; it defaults to the sys.stdout standard output stream if not passed. Any object with a file-like write(string) method may be passed, but real files should be already opened for output.

  • flush, added in 3.3, defaults to False. It allows prints to mandate that their text be flushed through the output stream immediately to any waiting recipients. Normally, whether printed output is buffered in memory or not is determined by file; passing a true value to flush forcibly flushes the stream.

The textual representation of each object to be printed is obtained by passing the object to the str built-in call (or its equivalent inside Python); as we’ve seen, this built-in returns a “user friendly” display string for any object.[26] With no arguments at all, the print function simply prints a newline character to the standard output stream, which usually displays a blank line.

The 3.X print function in action

Printing in 3.X is probably simpler than some of its details may imply. To illustrate, let’s run some quick examples. The following prints a variety of object types to the default standard output stream, with the default separator and end-of-line formatting added (these are the defaults because they are the most common use case):

C:\code> c:\python33\python
>>> print()                                      # Display a blank line

>>> x = 'spam'
>>> y = 99
>>> z = ['eggs']
>>>
>>> print(x, y, z)                               # Print three objects per defaults
spam 99 ['eggs']

There’s no need to convert objects to strings here, as would be required for file write methods. By default, print calls add a space between the objects printed. To suppress this, send an empty string to the sep keyword argument, or send an alternative separator of your choosing:

>>> print(x, y, z, sep='')                       # Suppress separator
spam99['eggs']
>>>
>>> print(x, y, z, sep=', ')                     # Custom separator
spam, 99, ['eggs']

Also by default, print adds an end-of-line character to terminate the output line. You can suppress this and avoid the line break altogether by passing an empty string to the end keyword argument, or you can pass a different terminator of your own including a \n character to break the line manually if desired (the second of the following is two statements on one line, separated by a semicolon):

>>> print(x, y, z, end='')                        # Suppress line break
spam 99 ['eggs']>>>
>>>
>>> print(x, y, z, end=''); print(x, y, z)        # Two prints, same output line
spam 99 ['eggs']spam 99 ['eggs']
>>> print(x, y, z, end='...\n')                   # Custom line end
spam 99 ['eggs']...
>>>

You can also combine keyword arguments to specify both separators and end-of-line strings—they may appear in any order but must appear after all the objects being printed:

>>> print(x, y, z, sep='...', end='!\n')          # Multiple keywords
spam...99...['eggs']!
>>> print(x, y, z, end='!\n', sep='...')          # Order doesn't matter
spam...99...['eggs']!

Here is how the file keyword argument is used—it directs the printed text to an open output file or other compatible object for the duration of the single print (this is really a form of stream redirection, a topic we will revisit later in this section):

>>> print(x, y, z, sep='...', file=open('data.txt', 'w'))      # Print to a file
>>> print(x, y, z)                                             # Back to stdout
spam 99 ['eggs']
>>> print(open('data.txt').read())                             # Display file text
spam...99...['eggs']

Finally, keep in mind that the separator and end-of-line options provided by print operations are just conveniences. If you need to display more specific formatting, don’t print this way. Instead, build up a more complex string ahead of time or within the print itself using the string tools we met in Chapter 7, and print the string all at once:

>>> text = '%s: %-.4f, %05d' % ('Result', 3.14159, 42)
>>> print(text)
Result: 3.1416, 00042
>>> print('%s: %-.4f, %05d' % ('Result', 3.14159, 42))
Result: 3.1416, 00042

As we’ll see in the next section, almost everything we’ve just seen about the 3.X print function also applies directly to 2.X print statements—which makes sense, given that the function was intended to both emulate and improve upon 2.X printing support.

The Python 2.X print Statement

As mentioned earlier, printing in Python 2.X uses a statement with unique and specific syntax, rather than a built-in function. In practice, though, 2.X printing is mostly a variation on a theme; with the exception of separator strings (which are supported in 3.X but not 2.X) and flushes on prints (available as of 3.3 only), everything we can do with the 3.X print function has a direct translation to the 2.X print statement.

Statement forms

Table 11-5 lists the print statement’s forms in Python 2.X and gives their Python 3.X print function equivalents for reference. Notice that the comma is significant in print statements—it separates objects to be printed, and a trailing comma suppresses the end-of-line character normally added at the end of the printed text (not to be confused with tuple syntax!). The >> syntax, normally used as a bitwise right-shift operation, is used here as well, to specify a target output stream other than the sys.stdout default.

Table 11-5. Python 2.X print statement forms

Python 2.X statement

Python 3.X equivalent

Interpretation

print x, y

print(x, y)

Print objects’ textual forms to sys.stdout; add a space between the items and an end-of-line at the end

print x, y,

print(x, y, end='')

Same, but don’t add end-of-line at end of text

print >> afile, x, y

print(x, y, file=afile)

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

The 2.X print statement in action

Although the 2.X print statement has more unique syntax than the 3.X function, it’s similarly easy to use. Let’s turn to some basic examples again. The 2.X print statement adds a space between the items separated by commas and by default adds a line break at the end of the current output line:

C:\code> c:\python27\python
>>> x = 'a'
>>> y = 'b'
>>> print x, y
a b

This formatting is just a default; you can choose to use it or not. To suppress the line break 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 11-5 (the following uses a semicolon to separate two statements on one line again):

>>> print x, y,; print x, y
a b a b

To suppress the space between items, again, don’t print this way. Instead, build up an output string using the string concatenation and formatting tools covered in Chapter 7, and print the string all at once:

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

As you can see, apart from their special syntax for usage modes, 2.X print statements are roughly as simple to use as 3.X’s function. The next section uncovers the way that files are specified in 2.X prints.

Print Stream Redirection

In both Python 3.X and 2.X, printing sends text to the standard output stream by default. However, it’s often useful to send it elsewhere—to a text file, for example, to save results for later use or testing purposes. Although such redirection can be accomplished in system shells outside Python itself, it turns out to be just as easy to redirect a script’s streams from within the script.

The Python “hello world” program

Let’s start off with the usual (and largely pointless) language benchmark—the “hello world” program. To print a “hello world” message in Python, simply print the string per your version’s print operation:

>>> print('hello world')               # Print a string object in 3.X
hello world

>>> print 'hello world'                # Print a string object in 2.X
hello world

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

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

This code isn’t exactly an earth-shattering piece of software mastery, but it serves to illustrate printing behavior. Really, the print operation is just an ergonomic feature of Python—it provides a simple interface to the sys.stdout object, with a bit of default formatting. In fact, if you enjoy working harder than you must, 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 operation hides most of those details, providing a simple tool for simple printing tasks.

Manual stream redirection

So, why did I just show you the hard way to print? The sys.stdout print equivalent turns out to be the basis of a common technique in Python. In general, print and sys.stdout are directly related as follows. This statement:

print(X, Y)                            # Or, in 2.X: print X, Y

is equivalent to the longer:

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

which manually performs a string conversion with str, adds a separator and newline with +, and calls the output stream’s write method. Which would you rather code? (He says, hoping to underscore the programmer-friendly nature of prints...)

Obviously, the long form isn’t all that useful for printing by itself. However, it is useful to know that this is exactly what print operations do because it is possible to reassign sys.stdout to something different from the standard output stream. In other words, this equivalence provides a way of making your print operations send their text to other places. For example:

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

Here, we reset sys.stdout to a manually opened file named log.txt, located in the script’s working directory and opened in append mode (so we add to its current content). After the reset, every print operation anywhere in the program will write its text to the end of the file log.txt instead of to the original output stream. The print operations are happy to keep calling sys.stdout’s write method, no matter what sys.stdout happens to refer to. Because there is just one sys module in your process, assigning sys.stdout this way will redirect every print anywhere in your program.

In fact, as the sidebar Why You Will Care: print and stdout will explain, you can even reset sys.stdout to an object that isn’t a file at all, as long as it has the expected interface: a method named write to receive the printed text string argument. When that object is a class, printed text can be routed and processed arbitrarily per a write method you code yourself.

This trick of resetting the output stream might be more useful for programs originally coded with print statements. If you know that output should go to a file to begin with, you can always call file write methods instead. To redirect the output of a print-based program, though, resetting sys.stdout provides a convenient alternative to changing every print statement or using system shell-based redirection syntax.

In other roles, streams may be reset to objects that display them in pop-up windows in GUIs, colorize then in IDEs like IDLE, and so on. It’s a general technique.

Automatic stream redirection

Although redirecting printed text by assigning sys.stdout is a useful tool, a 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. Because sys.stdout is just a normal file object, though, you can always save it and restore it if needed:[27]

C:\code> c:\python33\python
>>> import sys
>>> temp = sys.stdout                   # Save for restoring later
>>> sys.stdout = open('log.txt', 'a')   # Redirect prints to a file
>>> print('spam')                       # Prints go to file, not here
>>> print(1, 2, 3)
>>> sys.stdout.close()                  # Flush output to disk
>>> sys.stdout = temp                   # Restore original stream

>>> print('back here')                  # Prints show up here again
back here
>>> print(open('log.txt').read())       # Result of earlier prints
spam
1 2 3

As you can see, though, manual saving and restoring of the original output stream like this involves quite a bit of extra work. Because this crops up fairly often, a print extension is available to make it unnecessary.

In 3.X, the file keyword allows a single print call to send its text to the write method of a file (or file-like object), without actually resetting sys.stdout. Because the redirection is temporary, normal print calls keep printing to the original output stream. In 2.X, a print statement that begins with a >> followed by an output file object (or other compatible object) has the same effect. For example, the following again sends printed text to a file named log.txt:

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

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

These redirected forms of print are handy if you need to print to both files and the standard output stream in the same program. If you use these forms, however, be sure to give them a file object (or an object that has the same write method as a file object), not a file’s name string. Here is the technique in action:

C:\code> c:\python33\python
>>> log = open('log.txt', 'w')
>>> print(1, 2, 3, file=log)            # For 2.X: print >> log, 1, 2, 3
>>> print(4, 5, 6, file=log)
>>> log.close()
>>> print(7, 8, 9)                      # For 2.X: print 7, 8, 9
7 8 9
>>> print(open('log.txt').read())
1 2 3
4 5 6

These extended forms of print are also commonly used to print error messages to the standard error stream, available to your script as the preopened file object sys.stderr. You can either use its file write methods and format the output manually, or print with redirection syntax:

>>> import sys
>>> sys.stderr.write(('Bad!' * 8) + '\n')
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!

>>> print('Bad!' * 8, file=sys.stderr)     # In 2.X: print >> sys.stderr, 'Bad!' * 8
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!

Now that you know all about print redirections, the equivalence between printing and file write methods should be fairly obvious. The following interaction prints both ways in 3.X, then redirects the output to an external file to verify that the same text is printed:

>>> X = 1; Y = 2
>>> print(X, Y)                                            # Print: the easy way
1 2
>>> import sys                                             # Print: the hard way
>>> sys.stdout.write(str(X) + ' ' + str(Y) + '\n')
1 2
4
>>> print(X, Y, file=open('temp1', 'w'))                   # Redirect text to file

>>> open('temp2', 'w').write(str(X) + ' ' + str(Y) + '\n') # Send to file manually
4
>>> print(open('temp1', 'rb').read())                      # Binary mode for bytes
b'1 2\r\n'
>>> print(open('temp2', 'rb').read())
b'1 2\r\n'

As you can see, unless you happen to enjoy typing, print operations are usually the best option for displaying text. For another example of the equivalence between prints and file writes, watch for a 3.X print function emulation example in Chapter 18; it uses this code pattern to provide a general 3.X print function equivalent for use in Python 2.X.

Version-Neutral Printing

Finally, if you need your prints to work on both Python lines, you have some options. This is true whether you’re writing 2.X code that strives for 3.X compatibility, or 3.X code that aims to support 2.X too.

2to3 converter

For one, you can code 2.X print statements and let 3.X’s 2to3 conversion script translate them to 3.X function calls automatically. See the Python 3.X manuals for more details about this script; it attempts to translate 2.X code to run under 3.X—a useful tool, but perhaps more than you want to make just your print operations version-neutral. A related tool named 3to2 attempts to do the inverse: convert 3.X code to run on 2.X; see Appendix C for more information.

Importing from __future__

Alternatively, you can code 3.X print function calls in code to be run by 2.X, by enabling the function call variant with a statement like the following coded at the top of a script, or anywhere in an interactive session:

from __future__ import print_function

This statement changes 2.X to support 3.X’s print functions exactly. This way, you can use 3.X print features and won’t have to change your prints if you later migrate to 3.X. Two usage notes here:

  • This statement is simply ignored if it appears in code run by 3.X—it doesn’t hurt if included in 3.X code for 2.X compatibility.

  • This statement must appear at the top of each file that prints in 2.X—because it modifies that parser for a single file only, it’s not enough to import another file that includes this statement.

Neutralizing display differences with code

Also keep in mind that simple prints, like those in the first row of Table 11-5, work in either version of Python—because any expression may be enclosed in parentheses, we can always pretend to be calling a 3.X print function in 2.X by adding outer parentheses. The main downside to this is that it makes a tuple out of your printed objects if there are more than one, or none—they will print with extra enclosing parentheses. In 3.X, for example, any number of objects may be listed in the call’s parentheses:

C:\code> c:\python33\python
>>> print('spam')                       # 3.X print function call syntax
spam
>>> print('spam', 'ham', 'eggs')        # These are multiple arguments
spam ham eggs

The first of these works the same in 2.X, but the second generates a tuple in the output:

C:\code> c:\python27\python
>>> print('spam')                       # 2.X print statement, enclosing parens
spam
>>> print('spam', 'ham', 'eggs')        # This is really a tuple object!
('spam', 'ham', 'eggs')

The same applies when there are no objects printed to force a line-feed: 2.X shows a tuple, unless you print an empty string:

c:\code> py −2
>> print()                              # This is just a line-feed on 3.X
()
>>> print('')                           # This is a line-feed in both 2.X and 3.X

Strictly speaking, outputs may in some cases differ in more than just extra enclosing parentheses in 2.X. If you look closely at the preceding results, you’ll notice that the strings also print with enclosing quotes in 2.X only. This is because objects may print differently when nested in another object than they do as top-level items. Technically, nested appearances display with repr and top-level objects with str—the two alternative display formats we noted in Chapter 5.

Here this just means extra quotes around strings nested in the tuple that is created for printing multiple parenthesized items in 2.X. Displays of nested objects can differ much more for other object types, though, and especially for class objects that define alternative displays with operator overloading—a topic we’ll cover in Part VI in general and Chapter 30 in particular.

To be truly portable without enabling 3.X prints everywhere, and to sidestep display difference for nested appearances, you can always format the print string as a single object to unify displays across versions, using the string formatting expression or method call, or other string tools that we studied in Chapter 7:

>>> print('%s %s %s' % ('spam', 'ham', 'eggs'))
spam ham eggs
>>> print('{0} {1} {2}'.format('spam', 'ham', 'eggs'))
spam ham eggs
>>> print('answer: ' + str(42))
answer: 42

Of course, if you can use 3.X exclusively you can forget such mappings entirely, but many Python programmers will at least encounter, if not write, 2.X code and systems for some time to come. We’ll use both __future__ and version-neutral code to achieve 2.X/3.X portability in many examples in this book.

Note

I use Python 3.X print function calls throughout this book. I’ll often make prints version-neutral, and will usually warn you when the results may differ in 2.X, but I sometimes don’t, so please consider this note a blanket warning. If you see extra parentheses in your printed text in 2.X, either drop the parentheses in your print statements, import 3.X prints from the __future__, recode your prints using the version-neutral scheme outlined here, or learn to love superfluous text.



[26] Technically, printing uses the equivalent of str in the internal implementation of Python, but the effect is the same. Besides this to-string conversion role, str is also the name of the string data type and can be used to decode Unicode strings from raw bytes with an extra encoding argument, as we’ll learn in Chapter 37; this latter role is an advanced usage that we can safely ignore here.

[27] In both 2.X and 3.X you may also be able to use the __stdout__ attribute in the sys module, which refers to the original value sys.stdout had at program startup time. You still need to restore sys.stdout to sys.__stdout__ to go back to this original stream value, though. See the sys module documentation for more details.