Skip to content

Commit ced350b

Browse files
authored
bpo-28626: rearrange discussion of output formatting to encourage f-strings (#6036)
The 'output formatting' section of the tutorial talks a lot about manual formatting with things like .rjust() and .zfill(), with only a passing reference to 3.6's new f-strings. This doesn't drop all of the old material, but it does rearrange the topics into a more modern order: f-strings first, discussing formatting specifiers a bit; then calling .format(); finally manual formatting with .ljust().
1 parent caccca7 commit ced350b

File tree

1 file changed

+138
-89
lines changed

1 file changed

+138
-89
lines changed

Doc/tutorial/inputoutput.rst

Lines changed: 138 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,39 @@ of file objects; the standard output file can be referenced as ``sys.stdout``.
2020
See the Library Reference for more information on this.)
2121

2222
Often you'll want more control over the formatting of your output than simply
23-
printing space-separated values. There are two ways to format your output; the
24-
first way is to do all the string handling yourself; using string slicing and
25-
concatenation operations you can create any layout you can imagine. The
26-
string type has some methods that perform useful operations for padding
27-
strings to a given column width; these will be discussed shortly. The second
28-
way is to use :ref:`formatted string literals <f-strings>`, or the
29-
:meth:`str.format` method.
23+
printing space-separated values. There are several ways to format output.
3024

31-
The :mod:`string` module contains a :class:`~string.Template` class which offers
32-
yet another way to substitute values into strings.
25+
* To use :ref:`formatted string literals <tut-f-strings>`, begin a string
26+
with ``f`` or ``F`` before the opening quotation mark or triple quotation mark.
27+
Inside this string, you can write a Python expression between ``{`` and ``}``
28+
characters that can refer to variables or literal values.
3329

34-
One question remains, of course: how do you convert values to strings? Luckily,
35-
Python has ways to convert any value to a string: pass it to the :func:`repr`
36-
or :func:`str` functions.
30+
::
31+
32+
>>> year = 2016 ; event = 'Referendum'
33+
>>> f'Results of the {year} {event}'
34+
'Results of the 2016 Referendum'
35+
36+
* The :meth:`str.format` method of strings requires more manual
37+
effort. You'll still use ``{`` and ``}`` to mark where a variable
38+
will be substituted and can provide detailed formatting directives,
39+
but you'll also need to provide the information to be formatted.
40+
41+
::
42+
43+
>>> yes_votes = 42_572_654 ; no_votes = 43_132_495
44+
>>> percentage = (yes_votes/(yes_votes+no_votes)
45+
>>> '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage))
46+
' 42572654 YES votes 49.67%'
47+
48+
* Finally, you can do all the string handling yourself by using string slicing and
49+
concatenation operations to create any layout you can imagine. The
50+
string type has some methods that perform useful operations for padding
51+
strings to a given column width.
52+
53+
When you don't need fancy output but just want a quick display of some
54+
variables for debugging purposes, you can convert any value to a string with
55+
the :func:`repr` or :func:`str` functions.
3756

3857
The :func:`str` function is meant to return representations of values which are
3958
fairly human-readable, while :func:`repr` is meant to generate representations
@@ -67,60 +86,57 @@ Some examples::
6786
... repr((x, y, ('spam', 'eggs')))
6887
"(32.5, 40000, ('spam', 'eggs'))"
6988

70-
Here are two ways to write a table of squares and cubes::
89+
The :mod:`string` module contains a :class:`~string.Template` class that offers
90+
yet another way to substitute values into strings, using placeholders like
91+
``$x`` and replacing them with values from a dictionary, but offers much less
92+
control of the formatting.
7193

72-
>>> for x in range(1, 11):
73-
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
74-
... # Note use of 'end' on previous line
75-
... print(repr(x*x*x).rjust(4))
76-
...
77-
1 1 1
78-
2 4 8
79-
3 9 27
80-
4 16 64
81-
5 25 125
82-
6 36 216
83-
7 49 343
84-
8 64 512
85-
9 81 729
86-
10 100 1000
8794

88-
>>> for x in range(1, 11):
89-
... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
95+
.. _tut-f-strings:
96+
97+
Formatted String Literals
98+
-------------------------
99+
100+
:ref:`Formatted string literals <f-strings>` (also called f-strings for
101+
short) let you include the value of Python expressions inside a string by
102+
prefixing the string with ``f`` or ``F`` and writing expressions as
103+
``{expression}``.
104+
105+
An optional format specifier can follow the expression. This allows greater
106+
control over how the value is formatted. The following example rounds pi to
107+
three places after the decimal::
108+
109+
>>> import math
110+
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
111+
112+
Passing an integer after the ``':'`` will cause that field to be a minimum
113+
number of characters wide. This is useful for making columns line up. ::
114+
115+
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
116+
>>> for name, phone in table.items():
117+
... print(f'{name:10} ==> {phone:10d}')
90118
...
91-
1 1 1
92-
2 4 8
93-
3 9 27
94-
4 16 64
95-
5 25 125
96-
6 36 216
97-
7 49 343
98-
8 64 512
99-
9 81 729
100-
10 100 1000
119+
Sjoerd ==> 4127
120+
Jack ==> 4098
121+
Dcab ==> 7678
101122

102-
(Note that in the first example, one space between each column was added by the
103-
way :func:`print` works: by default it adds spaces between its arguments.)
123+
Other modifiers can be used to convert the value before it is formatted.
124+
``'!a'`` applies :func:`ascii`, ``'!s'`` applies :func:`str`, and ``'!r'``
125+
applies :func:`repr`::
104126

105-
This example demonstrates the :meth:`str.rjust` method of string
106-
objects, which right-justifies a string in a field of a given width by padding
107-
it with spaces on the left. There are similar methods :meth:`str.ljust` and
108-
:meth:`str.center`. These methods do not write anything, they just return a
109-
new string. If the input string is too long, they don't truncate it, but
110-
return it unchanged; this will mess up your column lay-out but that's usually
111-
better than the alternative, which would be lying about a value. (If you
112-
really want truncation you can always add a slice operation, as in
113-
``x.ljust(n)[:n]``.)
127+
>>> animals = 'eels'
128+
>>> print(f'My hovercraft is full of {animals}.')
129+
My hovercraft is full of eels.
130+
>>> print('My hovercraft is full of {animals !r}.')
131+
My hovercraft is full of 'eels'.
114132

115-
There is another method, :meth:`str.zfill`, which pads a numeric string on the
116-
left with zeros. It understands about plus and minus signs::
133+
For a reference on these format specifications, see
134+
the reference guide for the :ref:`formatspec`.
117135

118-
>>> '12'.zfill(5)
119-
'00012'
120-
>>> '-3.14'.zfill(7)
121-
'-003.14'
122-
>>> '3.14159265359'.zfill(5)
123-
'3.14159265359'
136+
.. _tut-string-format:
137+
138+
The String format() Method
139+
--------------------------
124140

125141
Basic usage of the :meth:`str.format` method looks like this::
126142

@@ -150,34 +166,6 @@ Positional and keyword arguments can be arbitrarily combined::
150166
other='Georg'))
151167
The story of Bill, Manfred, and Georg.
152168

153-
``'!a'`` (apply :func:`ascii`), ``'!s'`` (apply :func:`str`) and ``'!r'``
154-
(apply :func:`repr`) can be used to convert the value before it is formatted::
155-
156-
>>> contents = 'eels'
157-
>>> print('My hovercraft is full of {}.'.format(contents))
158-
My hovercraft is full of eels.
159-
>>> print('My hovercraft is full of {!r}.'.format(contents))
160-
My hovercraft is full of 'eels'.
161-
162-
An optional ``':'`` and format specifier can follow the field name. This allows
163-
greater control over how the value is formatted. The following example
164-
rounds Pi to three places after the decimal.
165-
166-
>>> import math
167-
>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))
168-
The value of PI is approximately 3.142.
169-
170-
Passing an integer after the ``':'`` will cause that field to be a minimum
171-
number of characters wide. This is useful for making tables pretty. ::
172-
173-
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
174-
>>> for name, phone in table.items():
175-
... print('{0:10} ==> {1:10d}'.format(name, phone))
176-
...
177-
Jack ==> 4098
178-
Dcab ==> 7678
179-
Sjoerd ==> 4127
180-
181169
If you have a really long format string that you don't want to split up, it
182170
would be nice if you could reference the variables to be formatted by name
183171
instead of by position. This can be done by simply passing the dict and using
@@ -198,10 +186,71 @@ notation. ::
198186
This is particularly useful in combination with the built-in function
199187
:func:`vars`, which returns a dictionary containing all local variables.
200188

189+
As an example, the following lines produce a tidily-aligned
190+
set of columns giving integers and their squares and cubes::
191+
192+
>>> for x in range(1, 11):
193+
... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
194+
...
195+
1 1 1
196+
2 4 8
197+
3 9 27
198+
4 16 64
199+
5 25 125
200+
6 36 216
201+
7 49 343
202+
8 64 512
203+
9 81 729
204+
10 100 1000
205+
201206
For a complete overview of string formatting with :meth:`str.format`, see
202207
:ref:`formatstrings`.
203208

204209

210+
Manual String Formatting
211+
------------------------
212+
213+
Here's the same table of squares and cubes, formatted manually::
214+
215+
>>> for x in range(1, 11):
216+
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
217+
... # Note use of 'end' on previous line
218+
... print(repr(x*x*x).rjust(4))
219+
...
220+
1 1 1
221+
2 4 8
222+
3 9 27
223+
4 16 64
224+
5 25 125
225+
6 36 216
226+
7 49 343
227+
8 64 512
228+
9 81 729
229+
10 100 1000
230+
231+
(Note that the one space between each column was added by the
232+
way :func:`print` works: it always adds spaces between its arguments.)
233+
234+
The :meth:`str.rjust` method of string objects right-justifies a string in a
235+
field of a given width by padding it with spaces on the left. There are
236+
similar methods :meth:`str.ljust` and :meth:`str.center`. These methods do
237+
not write anything, they just return a new string. If the input string is too
238+
long, they don't truncate it, but return it unchanged; this will mess up your
239+
column lay-out but that's usually better than the alternative, which would be
240+
lying about a value. (If you really want truncation you can always add a
241+
slice operation, as in ``x.ljust(n)[:n]``.)
242+
243+
There is another method, :meth:`str.zfill`, which pads a numeric string on the
244+
left with zeros. It understands about plus and minus signs::
245+
246+
>>> '12'.zfill(5)
247+
'00012'
248+
>>> '-3.14'.zfill(7)
249+
'-003.14'
250+
>>> '3.14159265359'.zfill(5)
251+
'3.14159265359'
252+
253+
205254
Old string formatting
206255
---------------------
207256

@@ -211,8 +260,8 @@ to the right argument, and returns the string resulting from this formatting
211260
operation. For example::
212261

213262
>>> import math
214-
>>> print('The value of PI is approximately %5.3f.' % math.pi)
215-
The value of PI is approximately 3.142.
263+
>>> print('The value of pi is approximately %5.3f.' % math.pi)
264+
The value of pi is approximately 3.142.
216265

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

0 commit comments

Comments
 (0)