AI Features

f-strings Containing Python Code

Learn how to use Python f-strings and explore format specifiers for versatile string formatting.

Overview

We aren’t restricted to interpolating the values of simple string variables into an f-string template. Any primitives, such as integers or floats, can be formatted. More interestingly, complex objects, including lists, tuples, dictionaries, and arbitrary objects, can be used, and we can access indexes and variables or call functions on those objects from within the format string.

Example

For example, if our email message had grouped the From and To email addresses into a tuple and placed the subject and message in a dictionary, for some reason (perhaps because that’s the input required for an existing send_mail function we want to use), we can format it like this:

emails = ("steve@example.com", "dusty@example.com")
message = {
"subject": "Next Chapter",
"message": "Here's the next chapter to review!",
}
formatted = f"""
From: <{emails[0]}>
To: <{emails[1]}>
Subject: {message['subject']} ...
{message['message']}
"""

The variables inside the braces in the template string look a little weird, so let’s look at what they’re doing. The two email addresses are looked up by the expression emails[x], where x is either 0 or 1. This is an ordinary tuple indexing operation, so emails[0] refers to the first item in the emails tuple. Similarly, the expression message['subject'] gets an item from a dictionary.

This works out particularly well when we have a more complex object to display. We can extract object attributes and properties and even call methods inside the f-string. Let’s change our email message data once again, this time to a class:

class Notification:
def __init__(
self,
from_addr: str,
to_addr: str,
subject: str,
message: str
) -> None:
self.from_addr = from_addr
self.to_addr = to_addr
self.subject = subject
self._message = message
def message(self):
return self._message

Here’s an instance of the Notification class:

email = Notification( "dusty@example.com",
"steve@example.com",
"Comments on the Chapter",
"Can we emphasize Python 3.9 type hints?", )

We can use this email instance to fill in an f-string as follows:

formatted = f"""
From: <{email.from_addr}>
To: <{email.to_addr}>
Subject: {email.subject}
{email.message()}
"""

Pretty much any Python code that we would expect to return a string (or a value that can convert to a string with the str() function) can be executed inside an f-string. As an example of how powerful it can get, we can even use a list comprehension or ternary operator in a format string ...

Ask