7.Input and Output

There are several ways to present the output of a program; data can be printedin a human-readable form, or written to a file for future use. This chapter willdiscuss some of the possibilities.

7.1.Fancier Output Formatting

So far we’ve encountered two ways of writing values:expression statements andtheprint statement. (A third way is using thewrite() methodof file objects; the standard output file can be referenced assys.stdout.See the Library Reference for more information on this.)

Often you’ll want more control over the formatting of your output than simplyprinting space-separated values. There are two ways to format your output; thefirst way is to do all the string handling yourself; using string slicing andconcatenation operations you can create any layout you can imagine. Thestring types have some methods that perform useful operations for paddingstrings to a given column width; these will be discussed shortly. The secondway is to use thestr.format() method.

Thestring module contains aTemplate class which offersyet another way to substitute values into strings.

One question remains, of course: how do you convert values to strings? Luckily,Python has ways to convert any value to a string: pass it to therepr()orstr() functions.

Thestr() function is meant to return representations of values which arefairly human-readable, whilerepr() is meant to generate representationswhich can be read by the interpreter (or will force aSyntaxError ifthere is no equivalent syntax). For objects which don’t have a particularrepresentation for human consumption,str() will return the same value asrepr(). Many values, such as numbers or structures like lists anddictionaries, have the same representation using either function. Strings andfloating point numbers, in particular, have two distinct representations.

Some examples:

>>>s='Hello, world.'>>>str(s)'Hello, world.'>>>repr(s)"'Hello, world.'">>>str(1.0/7.0)'0.142857142857'>>>repr(1.0/7.0)'0.14285714285714285'>>>x=10*3.25>>>y=200*200>>>s='The value of x is '+repr(x)+', and y is '+repr(y)+'...'>>>printsThe value of x is 32.5, and y is 40000...>>># The repr() of a string adds string quotes and backslashes:...hello='hello, world\n'>>>hellos=repr(hello)>>>printhellos'hello, world\n'>>># The argument to repr() may be any Python object:...repr((x,y,('spam','eggs')))"(32.5, 40000, ('spam', 'eggs'))"

Here are two ways to write a table of squares and cubes:

>>>forxinrange(1,11):...printrepr(x).rjust(2),repr(x*x).rjust(3),...# Note trailing comma on previous line...printrepr(x*x*x).rjust(4)... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000>>>forxinrange(1,11):...print'{0:2d}{1:3d}{2:4d}'.format(x,x*x,x*x*x)... 1   1    1 2   4    8 3   9   27 4  16   64 5  25  125 6  36  216 7  49  343 8  64  512 9  81  72910 100 1000

(Note that in the first example, one space between each column was added by thewayprint works: by default it adds spaces between its arguments.)

This example demonstrates thestr.rjust() method of stringobjects, which right-justifies a string in a field of a given width by paddingit with spaces on the left. There are similar methodsstr.ljust() andstr.center(). These methods do not write anything, they just return anew string. If the input string is too long, they don’t truncate it, butreturn it unchanged; this will mess up your column lay-out but that’s usuallybetter than the alternative, which would be lying about a value. (If youreally want truncation you can always add a slice operation, as inx.ljust(n)[:n].)

There is another method,str.zfill(), which pads a numeric string on theleft with zeros. It understands about plus and minus signs:

>>>'12'.zfill(5)'00012'>>>'-3.14'.zfill(7)'-003.14'>>>'3.14159265359'.zfill(5)'3.14159265359'

Basic usage of thestr.format() method looks like this:

>>>print'We are the{} who say "{}!"'.format('knights','Ni')We are the knights who say "Ni!"

The brackets and characters within them (called format fields) are replaced withthe objects passed into thestr.format() method. A number in thebrackets refers to the position of the object passed into thestr.format() method.

>>>print'{0} and{1}'.format('spam','eggs')spam and eggs>>>print'{1} and{0}'.format('spam','eggs')eggs and spam

If keyword arguments are used in thestr.format() method, their valuesare referred to by using the name of the argument.

>>>print'This{food} is{adjective}.'.format(...food='spam',adjective='absolutely horrible')This spam is absolutely horrible.

Positional and keyword arguments can be arbitrarily combined:

>>>print'The story of{0},{1}, and{other}.'.format('Bill','Manfred',...other='Georg')The story of Bill, Manfred, and Georg.

'!s' (applystr()) and'!r' (applyrepr()) can be used toconvert the value before it is formatted.

>>>importmath>>>print'The value of PI is approximately{}.'.format(math.pi)The value of PI is approximately 3.14159265359.>>>print'The value of PI is approximately{!r}.'.format(math.pi)The value of PI is approximately 3.141592653589793.

An optional':' and format specifier can follow the field name. This allowsgreater control over how the value is formatted. The following examplerounds Pi to three places after the decimal.

>>>importmath>>>print'The value of PI is approximately{0:.3f}.'.format(math.pi)The value of PI is approximately 3.142.

Passing an integer after the':' will cause that field to be a minimumnumber of characters wide. This is useful for making tables pretty.

>>>table={'Sjoerd':4127,'Jack':4098,'Dcab':7678}>>>forname,phoneintable.items():...print'{0:10} ==>{1:10d}'.format(name,phone)...Jack       ==>       4098Dcab       ==>       7678Sjoerd     ==>       4127

If you have a really long format string that you don’t want to split up, itwould be nice if you could reference the variables to be formatted by nameinstead of by position. This can be done by simply passing the dict and usingsquare brackets'[]' to access the keys

>>>table={'Sjoerd':4127,'Jack':4098,'Dcab':8637678}>>>print('Jack:{0[Jack]:d}; Sjoerd:{0[Sjoerd]:d}; '...'Dcab:{0[Dcab]:d}'.format(table))Jack: 4098; Sjoerd: 4127; Dcab: 8637678

This could also be done by passing the table as keyword arguments with the ‘**’notation.

>>>table={'Sjoerd':4127,'Jack':4098,'Dcab':8637678}>>>print'Jack:{Jack:d}; Sjoerd:{Sjoerd:d}; Dcab:{Dcab:d}'.format(**table)Jack: 4098; Sjoerd: 4127; Dcab: 8637678

This is particularly useful in combination with the built-in functionvars(), which returns a dictionary containing all local variables.

For a complete overview of string formatting withstr.format(), seeFormat String Syntax.

7.1.1.Old string formatting

The% operator can also be used for string formatting. It interprets theleft argument much like asprintf()-style format string to be appliedto the right argument, and returns the string resulting from this formattingoperation. For example:

>>>importmath>>>print'The value of PI is approximately%5.3f.'%math.piThe value of PI is approximately 3.142.

More information can be found in theString Formatting Operations section.

7.2.Reading and Writing Files

open() returns a file object, and is most commonly used with twoarguments:open(filename,mode).

>>>f=open('workfile','w')>>>printf<open file 'workfile', mode 'w' at 80a0960>

The first argument is a string containing the filename. The second argument isanother string containing a few characters describing the way in which the filewill be used.mode can be'r' when the file will only be read,'w'for only writing (an existing file with the same name will be erased), and'a' opens the file for appending; any data written to the file isautomatically added to the end.'r+' opens the file for both reading andwriting. Themode argument is optional;'r' will be assumed if it’somitted.

On Windows,'b' appended to the mode opens the file in binary mode, so thereare also modes like'rb','wb', and'r+b'. Python on Windows makesa distinction between text and binary files; the end-of-line characters in textfiles are automatically altered slightly when data is read or written. Thisbehind-the-scenes modification to file data is fine for ASCII text files, butit’ll corrupt binary data like that inJPEG orEXE files. Bevery careful to use binary mode when reading and writing such files. On Unix,it doesn’t hurt to append a'b' to the mode, so you can use itplatform-independently for all binary files.

7.2.1.Methods of File Objects

The rest of the examples in this section will assume that a file object calledf has already been created.

To read a file’s contents, callf.read(size), which reads some quantity ofdata and returns it as a string.size is an optional numeric argument. Whensize is omitted or negative, the entire contents of the file will be read andreturned; it’s your problem if the file is twice as large as your machine’smemory. Otherwise, at mostsize bytes are read and returned. If the end ofthe file has been reached,f.read() will return an empty string ("").

>>>f.read()'This is the entire file.\n'>>>f.read()''

f.readline() reads a single line from the file; a newline character (\n)is left at the end of the string, and is only omitted on the last line of thefile if the file doesn’t end in a newline. This makes the return valueunambiguous; iff.readline() returns an empty string, the end of the filehas been reached, while a blank line is represented by'\n', a stringcontaining only a single newline.

>>>f.readline()'This is the first line of the file.\n'>>>f.readline()'Second line of the file\n'>>>f.readline()''

For reading lines from a file, you can loop over the file object. This is memoryefficient, fast, and leads to simple code:

>>>forlineinf:        print line,This is the first line of the file.Second line of the file

If you want to read all the lines of a file in a list you can also uselist(f) orf.readlines().

f.write(string) writes the contents ofstring to the file, returningNone.

>>>f.write('This is a test\n')

To write something other than a string, it needs to be converted to a stringfirst:

>>>value=('the answer',42)>>>s=str(value)>>>f.write(s)

f.tell() returns an integer giving the file object’s current position in thefile, measured in bytes from the beginning of the file. To change the fileobject’s position, usef.seek(offset,from_what). The position is computedfrom addingoffset to a reference point; the reference point is selected bythefrom_what argument. Afrom_what value of 0 measures from the beginningof the file, 1 uses the current file position, and 2 uses the end of the file asthe reference point.from_what can be omitted and defaults to 0, using thebeginning of the file as the reference point.

>>>f=open('workfile','r+')>>>f.write('0123456789abcdef')>>>f.seek(5)# Go to the 6th byte in the file>>>f.read(1)'5'>>>f.seek(-3,2)# Go to the 3rd byte before the end>>>f.read(1)'d'

When you’re done with a file, callf.close() to close it and free up anysystem resources taken up by the open file. After callingf.close(),attempts to use the file object will automatically fail.

>>>f.close()>>>f.read()Traceback (most recent call last):  File"<stdin>", line1, in<module>ValueError:I/O operation on closed file

It is good practice to use thewith keyword when dealing with fileobjects. This has the advantage that the file is properly closed after itssuite finishes, even if an exception is raised on the way. It is also muchshorter than writing equivalenttry-finally blocks:

>>>withopen('workfile','r')asf:...read_data=f.read()>>>f.closedTrue

File objects have some additional methods, such asisatty() andtruncate() which are less frequently used; consult the LibraryReference for a complete guide to file objects.

7.2.2.Saving structured data withjson

Strings can easily be written to and read from a file. Numbers take a bit moreeffort, since theread() method only returns strings, which will have tobe passed to a function likeint(), which takes a string like'123'and returns its numeric value 123. When you want to save more complex datatypes like nested lists and dictionaries, parsing and serializing by handbecomes complicated.

Rather than having users constantly writing and debugging code to savecomplicated data types to files, Python allows you to use the popular datainterchange format calledJSON (JavaScript Object Notation). The standard module calledjson can take Pythondata hierarchies, and convert them to string representations; this process iscalledserializing. Reconstructing the data from the string representationis calleddeserializing. Between serializing and deserializing, thestring representing the object may have been stored in a file or data, orsent over a network connection to some distant machine.

Note

The JSON format is commonly used by modern applications to allow for dataexchange. Many programmers are already familiar with it, which makesit a good choice for interoperability.

If you have an objectx, you can view its JSON string representation with asimple line of code:

>>>importjson>>>json.dumps([1,'simple','list'])'[1, "simple", "list"]'

Another variant of thedumps() function, calleddump(),simply serializes the object to a file. So iff is afile objectopened for writing, we can do this:

json.dump(x,f)

To decode the object again, iff is afile object which hasbeen opened for reading:

x=json.load(f)

This simple serialization technique can handle lists and dictionaries, butserializing arbitrary class instances in JSON requires a bit of extra effort.The reference for thejson module contains an explanation of this.

See also

pickle - the pickle module

Contrary toJSON,pickle is a protocol which allowsthe serialization of arbitrarily complex Python objects. As such, it isspecific to Python and cannot be used to communicate with applicationswritten in other languages. It is also insecure by default:deserializing pickle data coming from an untrusted source can executearbitrary code, if the data was crafted by a skilled attacker.