bpo-28626: rearrange discussion of output formatting to encourage f-strings (GH-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().
(cherry picked from commit ced350b195
)
Co-authored-by: Andrew Kuchling <amk@amk.ca>
This commit is contained in:
parent
f5197ddfd0
commit
80a5f04592
|
@ -20,20 +20,39 @@ of file objects; the standard output file can be referenced as ``sys.stdout``.
|
|||
See the Library Reference for more information on this.)
|
||||
|
||||
Often you'll want more control over the formatting of your output than simply
|
||||
printing space-separated values. There are two ways to format your output; the
|
||||
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
|
||||
printing space-separated values. There are several ways to format output.
|
||||
|
||||
* To use :ref:`formatted string literals <tut-f-strings>`, begin a string
|
||||
with ``f`` or ``F`` before the opening quotation mark or triple quotation mark.
|
||||
Inside this string, you can write a Python expression between ``{`` and ``}``
|
||||
characters that can refer to variables or literal values.
|
||||
|
||||
::
|
||||
|
||||
>>> year = 2016 ; event = 'Referendum'
|
||||
>>> f'Results of the {year} {event}'
|
||||
'Results of the 2016 Referendum'
|
||||
|
||||
* The :meth:`str.format` method of strings requires more manual
|
||||
effort. You'll still use ``{`` and ``}`` to mark where a variable
|
||||
will be substituted and can provide detailed formatting directives,
|
||||
but you'll also need to provide the information to be formatted.
|
||||
|
||||
::
|
||||
|
||||
>>> yes_votes = 42_572_654 ; no_votes = 43_132_495
|
||||
>>> percentage = (yes_votes/(yes_votes+no_votes)
|
||||
>>> '{:-9} YES votes {:2.2%}'.format(yes_votes, percentage))
|
||||
' 42572654 YES votes 49.67%'
|
||||
|
||||
* Finally, you can do all the string handling yourself by using string slicing and
|
||||
concatenation operations to create any layout you can imagine. The
|
||||
string type has some methods that perform useful operations for padding
|
||||
strings to a given column width; these will be discussed shortly. The second
|
||||
way is to use :ref:`formatted string literals <f-strings>`, or the
|
||||
:meth:`str.format` method.
|
||||
strings to a given column width.
|
||||
|
||||
The :mod:`string` module contains a :class:`~string.Template` class which offers
|
||||
yet 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 the :func:`repr`
|
||||
or :func:`str` functions.
|
||||
When you don't need fancy output but just want a quick display of some
|
||||
variables for debugging purposes, you can convert any value to a string with
|
||||
the :func:`repr` or :func:`str` functions.
|
||||
|
||||
The :func:`str` function is meant to return representations of values which are
|
||||
fairly human-readable, while :func:`repr` is meant to generate representations
|
||||
|
@ -67,60 +86,57 @@ Some examples::
|
|||
... repr((x, y, ('spam', 'eggs')))
|
||||
"(32.5, 40000, ('spam', 'eggs'))"
|
||||
|
||||
Here are two ways to write a table of squares and cubes::
|
||||
The :mod:`string` module contains a :class:`~string.Template` class that offers
|
||||
yet another way to substitute values into strings, using placeholders like
|
||||
``$x`` and replacing them with values from a dictionary, but offers much less
|
||||
control of the formatting.
|
||||
|
||||
>>> for x in range(1, 11):
|
||||
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
|
||||
... # Note use of 'end' on previous line
|
||||
... print(repr(x*x*x).rjust(4))
|
||||
|
||||
.. _tut-f-strings:
|
||||
|
||||
Formatted String Literals
|
||||
-------------------------
|
||||
|
||||
:ref:`Formatted string literals <f-strings>` (also called f-strings for
|
||||
short) let you include the value of Python expressions inside a string by
|
||||
prefixing the string with ``f`` or ``F`` and writing expressions as
|
||||
``{expression}``.
|
||||
|
||||
An optional format specifier can follow the expression. This allows greater
|
||||
control over how the value is formatted. The following example rounds pi to
|
||||
three places after the decimal::
|
||||
|
||||
>>> import math
|
||||
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
|
||||
|
||||
Passing an integer after the ``':'`` will cause that field to be a minimum
|
||||
number of characters wide. This is useful for making columns line up. ::
|
||||
|
||||
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
|
||||
>>> for name, phone in table.items():
|
||||
... print(f'{name:10} ==> {phone:10d}')
|
||||
...
|
||||
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 729
|
||||
10 100 1000
|
||||
Sjoerd ==> 4127
|
||||
Jack ==> 4098
|
||||
Dcab ==> 7678
|
||||
|
||||
>>> for x in range(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 729
|
||||
10 100 1000
|
||||
Other modifiers can be used to convert the value before it is formatted.
|
||||
``'!a'`` applies :func:`ascii`, ``'!s'`` applies :func:`str`, and ``'!r'``
|
||||
applies :func:`repr`::
|
||||
|
||||
(Note that in the first example, one space between each column was added by the
|
||||
way :func:`print` works: by default it adds spaces between its arguments.)
|
||||
>>> animals = 'eels'
|
||||
>>> print(f'My hovercraft is full of {animals}.')
|
||||
My hovercraft is full of eels.
|
||||
>>> print('My hovercraft is full of {animals !r}.')
|
||||
My hovercraft is full of 'eels'.
|
||||
|
||||
This example demonstrates the :meth:`str.rjust` method of string
|
||||
objects, which right-justifies a string in a field of a given width by padding
|
||||
it with spaces on the left. There are similar methods :meth:`str.ljust` and
|
||||
:meth:`str.center`. These methods do not write anything, they just return a
|
||||
new string. If the input string is too long, they don't truncate it, but
|
||||
return it unchanged; this will mess up your column lay-out but that's usually
|
||||
better than the alternative, which would be lying about a value. (If you
|
||||
really want truncation you can always add a slice operation, as in
|
||||
``x.ljust(n)[:n]``.)
|
||||
For a reference on these format specifications, see
|
||||
the reference guide for the :ref:`formatspec`.
|
||||
|
||||
There is another method, :meth:`str.zfill`, which pads a numeric string on the
|
||||
left with zeros. It understands about plus and minus signs::
|
||||
.. _tut-string-format:
|
||||
|
||||
>>> '12'.zfill(5)
|
||||
'00012'
|
||||
>>> '-3.14'.zfill(7)
|
||||
'-003.14'
|
||||
>>> '3.14159265359'.zfill(5)
|
||||
'3.14159265359'
|
||||
The String format() Method
|
||||
--------------------------
|
||||
|
||||
Basic usage of the :meth:`str.format` method looks like this::
|
||||
|
||||
|
@ -150,34 +166,6 @@ Positional and keyword arguments can be arbitrarily combined::
|
|||
other='Georg'))
|
||||
The story of Bill, Manfred, and Georg.
|
||||
|
||||
``'!a'`` (apply :func:`ascii`), ``'!s'`` (apply :func:`str`) and ``'!r'``
|
||||
(apply :func:`repr`) can be used to convert the value before it is formatted::
|
||||
|
||||
>>> contents = 'eels'
|
||||
>>> print('My hovercraft is full of {}.'.format(contents))
|
||||
My hovercraft is full of eels.
|
||||
>>> print('My hovercraft is full of {!r}.'.format(contents))
|
||||
My hovercraft is full of 'eels'.
|
||||
|
||||
An optional ``':'`` and format specifier can follow the field name. This allows
|
||||
greater control over how the value is formatted. The following example
|
||||
rounds Pi to three places after the decimal.
|
||||
|
||||
>>> import math
|
||||
>>> 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 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('{0:10} ==> {1:10d}'.format(name, phone))
|
||||
...
|
||||
Jack ==> 4098
|
||||
Dcab ==> 7678
|
||||
Sjoerd ==> 4127
|
||||
|
||||
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 simply passing the dict and using
|
||||
|
@ -198,10 +186,71 @@ notation. ::
|
|||
This is particularly useful in combination with the built-in function
|
||||
:func:`vars`, which returns a dictionary containing all local variables.
|
||||
|
||||
As an example, the following lines produce a tidily-aligned
|
||||
set of columns giving integers and their squares and cubes::
|
||||
|
||||
>>> for x in range(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 729
|
||||
10 100 1000
|
||||
|
||||
For a complete overview of string formatting with :meth:`str.format`, see
|
||||
:ref:`formatstrings`.
|
||||
|
||||
|
||||
Manual String Formatting
|
||||
------------------------
|
||||
|
||||
Here's the same table of squares and cubes, formatted manually::
|
||||
|
||||
>>> for x in range(1, 11):
|
||||
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
|
||||
... # Note use of 'end' on previous line
|
||||
... print(repr(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 729
|
||||
10 100 1000
|
||||
|
||||
(Note that the one space between each column was added by the
|
||||
way :func:`print` works: it always adds spaces between its arguments.)
|
||||
|
||||
The :meth:`str.rjust` method of string objects right-justifies a string in a
|
||||
field of a given width by padding it with spaces on the left. There are
|
||||
similar methods :meth:`str.ljust` and :meth:`str.center`. These methods do
|
||||
not write anything, they just return a new string. If the input string is too
|
||||
long, they don't truncate it, but return it unchanged; this will mess up your
|
||||
column lay-out but that's usually better than the alternative, which would be
|
||||
lying about a value. (If you really want truncation you can always add a
|
||||
slice operation, as in ``x.ljust(n)[:n]``.)
|
||||
|
||||
There is another method, :meth:`str.zfill`, which pads a numeric string on the
|
||||
left 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'
|
||||
|
||||
|
||||
Old string formatting
|
||||
---------------------
|
||||
|
||||
|
@ -211,8 +260,8 @@ 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.
|
||||
>>> print('The value of pi is approximately %5.3f.' % math.pi)
|
||||
The value of pi is approximately 3.142.
|
||||
|
||||
More information can be found in the :ref:`old-string-formatting` section.
|
||||
|
||||
|
|
Loading…
Reference in New Issue