Python String Formatting

The situation with string formatting is complicated.

Once upon a time, Python introduced percent formatting. It uses "%" as a binary operator to render strings:

>>> drink = "coffee"
>>> price = 2.5
>>> message = "This %s costs $%.2f." % (drink, price)
>>> print(message)
This coffee costs $2.50.

Later in Python 2's history, a different style was introduced, called simply string formatting (yes, that's the official name). Its very different syntax makes any Python string a potential template, inserting values through the str.format() method.

>>> template = "This {} costs ${:.2f}."
>>> print(template.format(drink, price))
This coffee costs $2.50.

Python 3.6 introduces a third option, called f-strings. This lets you write literal strings, prefixed with an "f" character, interpolating values from the immediate context:

>>> message = f"This {drink} costs ${price:.02f}."
>>> print(message)
This coffee costs $2.50.

So... which do you use?

My guidance in a nutshell (with explanations below):

"Which should I use?" is a separate question from "which should a Python article use for its code examples?" I use str.format() in this blog, as well as in Powerful Python. That's because all modern Python versions support it, so I know everyone reading this can use it.

Someday, when Python versions before 3.6 are a distant memory, there will be no reason not to use f-strings. But when that happens, str.format() will still be important. There are string formatting situations where f-strings are awkward at best, and str.format() is well suited. In the meantime, there is a lot of Python code out there using str.format(), which you'll need to be able to read and understand. That's why I normally use str.format() in my writing. Conveniently, this also teaches much about f-strings; they are more similar than different, as the formatting codes are nearly identical. str.format() is also the only practical choice for most people reading this, and will be for years still.

You might wonder if the old percent-formatting has any place in modern Python. In fact, it does, due to the logging module. For better or worse, this important module is built on percent-formatting in a deep way. It's possible to use str.format() in new logging code, but requires special steps; and legacy logging code cannot be safely converted in an automated way. I recommend you just cooperate with the situation, and use percent-formatting for your log messages.


You might enjoy the Powerful Python book because it has a whole chapter on string formatting.