Python has at least six ways of formatting a string:
In [1]: world = "Earth"
# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'
# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'
# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'
# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'
# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'
In [7]: from string import Template
# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'
A brief history of the different methods:
printf
-style formatting has been around since Pythons infancyTemplate
class was introduced in Python 2.4format
method was introduced in Python 2.6 f
-strings were introduced in Python 3.6My questions are:
printf
-style formatting deprecated or going to be deprecated?Template class
, is the substitute
method deprecated or going to be deprecated? (I'm not talking about safe_substitute
, which as I understand it offers unique capabilities)Similar questions and why I think they're not duplicates:
Python string formatting: % vs. .format — treats only methods 1 and 2, and asks which one is better; my question is explicitly about deprecation in the light of the Zen of Python
String formatting options: pros and cons — treats only methods 1a and 1b in the question, 1 and 2 in the answer, and also nothing about deprecation
advanced string formatting vs template strings — mostly about methods 1 and 3, and doesn't address deprecation
String formatting expressions (Python) — answer mentions that the original '%' approach is planned to be deprecated. But what's the difference between planned to be deprecated, pending deprecation and actual deprecation? And the printf
-style method doesn't raise even a PendingDeprecationWarning
, so is this really going to be deprecated? This post is also quite old, so the information may be outdated.
The new .format()
method is meant to replace the old %
formatting syntax. The latter has been de-emphasised, (but not officially deprecated yet). The method documentation states as much:
This method of string formatting is the new standard in Python 3, and should be preferred to the
%
formatting described in String Formatting Operations in new code.
(Emphasis mine).
To maintain backwards compatibility and to make transition easier, the old format has been left in place for now. From the original PEP 3101 proposal:
Backwards Compatibility
Backwards compatibility can be maintained by leaving the existing mechanisms in place. The new system does not collide with any of the method names of the existing string formatting techniques, so both systems can co-exist until it comes time to deprecate the older system.
Note the until it comes time to deprecate the older system; it hasn't been deprecated, but the new system is to be used whenever you write new code.
The new system has as an advantage that you can combine the tuple and dictionary approach of the old %
formatter:
"{greeting}, {0}".format(world, greeting='Hello')
and is extensible through the object.__format__()
hook used to handle formatting of individual values.
Note that the old system had %
and the Template
class, where the latter allows you to create subclasses that add or alter its behaviour. The new-style system has the Formatter
class to fill the same niche.
Python 3 has further stepped away from deprecation, instead giving you warning in the printf
-style String Formatting section:
Note: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the
str.format()
interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.
Python 3.6 also added formatted string literals, which in-line the expressions into the format strings. These are the fastest method of creating strings with interpolated values, and should be used instead of str.format()
wherever you can use a literal.