Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Simpler Debugging With f-Strings

In this lesson, you’ll learn how you can accomplish simpler debugging with f-strings. f-strings were introduced in Python 3.6, and have become very popular. They might be the most common reason for Python libraries only being supported on version 3.6 and later. An f-string is a formatted string literal. You can recognize it by the leading f:

>>>
>>> style = "formatted"
>>> f"This is a {style} string"
'This is a formatted string'

When you use f-strings, you can enclose variables and even expressions inside curly braces. They will then be evaluated at runtime and included in the string. You can have several expressions in one f-string:

>>>
>>> import math
>>> r = 3.6

>>> f"A circle with radius {r} has area {math.pi * r * r:.2f}"
'A circle with radius 3.6 has area 40.72'

In the last expression, {math.pi * r * r:.2f}, you also use a format specifier. Format specifiers are separated from the expressions with a colon.

.2f means that the area is formatted as a floating point number with 2 decimals. The format specifiers are the same as for .format(). See the official documentation for a full list of allowed format specifiers.

In Python 3.8, you can use assignment expressions inside f-strings. Just make sure to surround the assignment expression with parentheses:

>>>
>>> import math
>>> r = 3.8

>>> f"Diameter {(diam := 2 * r)} gives circumference {math.pi * diam:.2f}"
'Diameter 7.6 gives circumference 23.88'

However, the real f-news in Python 3.8 is the new debugging specifier. You can now add = at the end of an expression, and it will print both the expression and its value:

>>>
>>> python = 3.8
>>> f"{python=}"
'python=3.8'

This is a short-hand that will typically be most useful when you’re working interactively or adding print statements to debug your script. In earlier versions of Python, you needed to spell out the variable or expression twice to get the same information:

>>>
>>> python = 3.7
>>> f"python={python}"
'python=3.7'

You can add spaces around =, and use format specifiers as usual:

>>>
>>> name = "Eric"
>>> f"{name = }"
"name = 'Eric'"

>>> f"{name = :>10}"
'name =       Eric'

The >10 format specifier says that name should be right-aligned within a 10 character string. = works for more complex expressions as well:

>>>
>>> f"{name.upper()[::-1] = }"
"name.upper()[::-1] = 'CIRE'"

For more information about f-strings, see Python 3’s f-Strings: An Improved String Formatting Syntax (Guide) and the associated video course.

00:00 In this video, I’ll show you simpler debugging with f-strings. f-strings are formatted string literals. They were introduced in Python 3.6 and they allow variables or expressions to be enclosed inside curly braces within a string. Let me show you some examples. Start out with a variable named style. Assign style to a string of "formatted". To create an f-string you just start with the letter f and then start your string, and then where you’d like to add a variable or expression, you put it inside curly braces, like so. And as you can see, the f-string will insert the variable or expression right inside the string as it’s creating it. So again, you can enclose variables or expressions inside the curly braces, and they’re going to be evaluated at runtime.

00:43 You can even have several expressions in a single f-string. Say you import math and you say r = 3.6. r is going to be a radius.

00:52 And then you create an f-string,

00:55 f"A circle with a radius {r} has area"here’s where that expression comes in, and you’re taking .pi from math, so f"{math.pi * r * r}". You can specify a format by putting a colon (:) in here.

01:08 I can say that I want this to show up with two decimal places, so .2f. So, you can see the work that the f-string’s done replacing the variables and expressions and formatting them into a single string. The format specifiers are the same as for .format(), and I’ll include links to more information about the format specifiers and the official documentation for a full list of what’s allowed.

01:33 Let’s say you go a little further here and you create a new f-string with a different variable of r. Here you’re saying the f"Diameter "and you can use assignment expressions inside your f-string if you’d like. So here, you’re creating new variable diam and assigning it to 2 * r.

01:48 The f-string will evaluate and print that at runtime. One thing that you need to do, though, is if you’re going to use assignment expressions inside of f-strings, they need to be inside a pair of parentheses inside the curly braces.

02:07 Again, using the format specifier there. I’ve got a minor typo. So again, seeing how the f-string evaluates that in real time and using your new skill of assignment expressions.

02:16 This is not anything new outside of using the assignment expressions inside there. What does Python 3.8 add for f-strings, specifically?

02:26 If you’d like to learn a little more information about f-strings, check out the links below this video for a video course and in-depth article about f-strings.

02:34 Python 3.8 includes a new f-string debugging specifier. By adding an equal sign (=) at the end of an expression, it’ll print both the expression and its value.

02:44 This avoids the need to spell out the variable or expression twice. Let me give you some examples. You can create a variable such as python = 3.8, a float.

02:57 And you could use an f-string and inside of it, say python and then just add an equal sign (=). With this new debugging specifier, when you add that equal sign to the end of the expression, it’s going to print both the expression and its value, which is pretty neat. Before, in Python 3.7, you would have had to repeat the variable or expression twice to get the same information. And you can use spaces around the equal sign also, if you’d like,

03:25 adding one before and after.

03:32 And you can use format specifiers also.

03:36 This one’s going to specify that the name is going to be right-aligned with a 10-character string. You can use this equal sign for debugging even with more complex expressions as well. Here, you could say name and then apply a string method such as .upper(), and then also use indexing to reverse the string.

03:57 Then add the equal sign.

04:01 So here, it uppercased "Eric" and reversed it, all in one expression, with it printing both the expression and its value. So you can see how this could be really handy for debugging, especially with print statements in your code, or when you’re working interactively, like you’ve just been doing in a REPL.

04:18 In the next video, I’ll show you about the Python steering council.

Prabhath Kota on May 3, 2020

Thanks for the article. Good to know debugging with fstrings in 3.8 & optimizations

varelaautumn on Sept. 28, 2020

I know these are just supposed to be videos on some minor updates, but I really feel like these are things I’ll use a lot. Like the amount of times I type something along the lines of f'len(var) = {len(var)}' without realizing I could do this shortcut… oof.

I’m typing it in now on Python and I’m still in disbelief with the result it returns. What an incredibly helpful tool for debugging.

Become a Member to join the conversation.