Skip to content

Commit

Permalink
update the tutorial to use str.format
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminp committed May 26, 2008
1 parent c15205e commit f9ef988
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 32 deletions.
4 changes: 2 additions & 2 deletions Doc/tutorial/controlflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,8 @@ called with an arbitrary number of arguments. These arguments will be wrapped
up in a tuple. Before the variable number of arguments, zero or more normal
arguments may occur. ::

def fprintf(file, format, *args):
file.write(format % args)
def fprintf(file, template, *args):
file.write(template.format(args))


.. _tut-unpacking-arguments:
Expand Down
2 changes: 1 addition & 1 deletion Doc/tutorial/datastructures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ with the :func:`zip` function. ::
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print 'What is your %s? It is %s.' % (q, a)
... print 'What is your {0}? It is {1}.'.format(q, a)
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
Expand Down
2 changes: 1 addition & 1 deletion Doc/tutorial/errors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ the exception (allowing a caller to handle the exception as well)::
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error(%s): %s" % (errno, strerror)
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
except:
Expand Down
5 changes: 2 additions & 3 deletions Doc/tutorial/floatingpoint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@ that every float operation can suffer a new rounding error.
While pathological cases do exist, for most casual use of floating-point
arithmetic you'll see the result you expect in the end if you simply round the
display of your final results to the number of decimal digits you expect.
:func:`str` usually suffices, and for finer control see the discussion of
Python's ``%`` format operator: the ``%g``, ``%f`` and ``%e`` format codes
supply flexible and easy ways to round float results for display.
:func:`str` usually suffices, and for finer control see the :meth:`str.format`
method's format specifiers in :ref:`formatstrings`.


.. _tut-fp-error:
Expand Down
90 changes: 68 additions & 22 deletions Doc/tutorial/inputoutput.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,13 @@ first way is to do all the string handling yourself; using string slicing and
concatenation operations you can create any layout you can imagine. The
standard module :mod:`string` contains some useful operations for padding
strings to a given column width; these will be discussed shortly. The second
way is to use the ``%`` operator with a string as the left argument. The ``%``
operator interprets the left argument much like a :cfunc:`sprintf`\ -style
format string to be applied to the right argument, and returns the string
resulting from this formatting operation.
way is to use the :meth:`str.format` method.

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 the :func:`repr`
or :func:`str` functions. Reverse quotes (``````) are equivalent to
:func:`repr`, but they are no longer used in modern Python code and will likely
not be in future versions of the language.
:func:`repr`, but they are no longer used in modern Python code and are removed
in future versions of the language.

The :func:`str` function is meant to return representations of values which are
fairly human-readable, while :func:`repr` is meant to generate representations
Expand Down Expand Up @@ -94,7 +91,7 @@ Here are two ways to write a table of squares and cubes::
10 100 1000

>>> for x in range(1,11):
... print '%2d %3d %4d' % (x, x*x, x*x*x)
... print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)
...
1 1 1
2 4 8
Expand Down Expand Up @@ -129,42 +126,91 @@ with zeros. It understands about plus and minus signs::
>>> '3.14159265359'.zfill(5)
'3.14159265359'

Using the ``%`` operator looks like this::
Basic usage of the :meth:`str.format` method looks like this::

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

The brackets and characters within them (called format fields) are replaced with
the objects passed into the format method. The number in the brackets refers to
the position of the object passed into the 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 the format method, their values are 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.

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

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

If there is more than one format in the string, you need to pass a tuple as
right operand, as in this example::
Passing an integer after the ``':'`` will cause that field to be a minimum
number of characters wide. This is useful for making tables pretty.::

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print '%-10s ==> %10d' % (name, phone)
... print '{0:10} ==> {1:10d}'.format(name, phone)
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127

Most formats work exactly as in C and require that you pass the proper type;
however, if you don't you get an exception, not a core dump. The ``%s`` format
is more relaxed: if the corresponding argument is not a string object, it is
converted to string using the :func:`str` built-in function. Using ``*`` to
pass the width or precision in as a separate (integer) argument is supported.
The C formats ``%n`` and ``%p`` are not supported.

If you have a really long format string that you don't want to split up, it
would be nice if you could reference the variables to be formatted by name
instead of by position. This can be done by using form ``%(name)format``, as
shown here::
instead of by position. This can be done by simply passing the dict and using
square 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' % table
>>> 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 new built-in :func:`vars`
function, which returns a dictionary containing all local variables.

For a complete overview of string formating with :meth:`str.format`, see
:ref:`formatstrings`.


Old string formatting
---------------------

The ``%`` operator can also be used for string formatting. It interprets the
left argument much like a :cfunc:`sprintf`\ -style format string to be applied
to the right argument, and returns the string resulting from this formatting
operation. For example::

>>> import math
>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.

Since :meth:`str.format` is quite new, a lot of Python code still uses the ``%``
operator. However, because this old style of formatting will eventually removed
from the language :meth:`str.format` should generally be used.

More information can be found in the :ref:`string-formatting` section.


.. _tut-files:

Expand Down
8 changes: 6 additions & 2 deletions Doc/tutorial/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,13 @@ The built-in function :func:`len` returns the length of a string::
Both strings and Unicode strings support a large number of methods for
basic transformations and searching.

:ref:`new-string-formatting`
Information about string formatting with :meth:`str.format` is described
here.

:ref:`string-formatting`
The formatting operations invoked when strings and Unicode strings are the
left operand of the ``%`` operator are described in more detail here.
The old formatting operations invoked when strings and Unicode strings are
the left operand of the ``%`` operator are described in more detail here.


.. _tut-unicodestrings:
Expand Down
2 changes: 1 addition & 1 deletion Doc/tutorial/stdlib2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ placeholders such as the current date, image sequence number, or file format::
>>> for i, filename in enumerate(photofiles):
... base, ext = os.path.splitext(filename)
... newname = t.substitute(d=date, n=i, f=ext)
... print '%s --> %s' % (filename, newname)
... print '{0} --> {1}'.format(filename, newname)

img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
Expand Down

0 comments on commit f9ef988

Please sign in to comment.