F-String Debugging¶
Python 3.8 introduced the = specifier for f-strings, allowing expressions to display both their source and value.
This feature simplifies debugging by eliminating the need to manually write variable names.
x = 42
print(f"{x=}") # x=42
The output automatically includes the expression:
x=42
Basic Usage¶
The = specifier prints the expression and its evaluated value.
count = 100
name = "Bob"
active = True
print(f"{count=}") # count=100
print(f"{name=}") # name='Bob'
print(f"{active=}") # active=True
Expressions¶
The debug specifier works with any Python expression, not only variables.
x = 5
print(f"{x + 10=}") # x + 10=15
print(f"{x * 2=}") # x * 2=10
print(f"{x ** 2=}") # x ** 2=25
items = [1, 2, 3]
print(f"{len(items)=}") # len(items)=3
print(f"{sum(items)=}") # sum(items)=6
It also works with function calls and attributes:
def add(a, b):
return a + b
print(f"{add(2,3)=}") # add(2,3)=5
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(3,4)
print(f"{p.x=}, {p.y=}") # p.x=3, p.y=4
Combining with Format Specifiers¶
The = specifier can be combined with format specifiers.
value = 123.456789
print(f"{value=}") # value=123.456789
print(f"{value=:.2f}") # value=123.46
print(f"{value=:10.2f}") # value= 123.46
Numeric formatting works as expected:
large = 1234567
print(f"{large=:,}") # large=1,234,567
print(f"{large=:_}") # large=1_234_567
Spaces Around =¶
Whitespace inside the f-string is preserved.
x = 42
print(f"{x=}") # x=42
print(f"{x =}") # x =42
print(f"{x= }") # x= 42
print(f"{x = }") # x = 42
This allows you to control readability.
a, b, c = 1, 2, 3
print(f"{a=},{b=},{c=}") # compact
print(f"{a = }, {b = }, {c = }") # readable
Practical Debugging Patterns¶
Inspect multiple variables¶
def calculate(a, b, c):
result = (a + b) * c
print(f"{a=}, {b=}, {c=}, {result=}")
return result
Debug loops¶
items = ["apple", "banana", "cherry"]
for i, item in enumerate(items):
print(f"{i=}, {item=}")
Debug intermediate values¶
def complex_function(x, y):
print(f"ENTER: {x=}, {y=}")
intermediate = x * y
print(f"{intermediate=}")
result = intermediate ** 2
print(f"EXIT: {result=}")
return result
String Representation¶
By default the debug specifier uses repr().
name = "Alice"
print(f"{name=}") # name='Alice'
You can override this behavior:
print(f"{name=!s}") # name=Alice
print(f"{name=!r}") # name='Alice'
ASCII Representation¶
Use !a for ASCII-safe output.
text = "Héllo"
print(f"{text=}") # text='Héllo'
print(f"{text=!a}") # text='H\\xe9llo'
Limitations¶
The = specifier works only in f-strings.
x = 42
print(f"{x=}") # works
It does not work with str.format():
fmt = "{x=}"
# fmt.format(x=42) # does not produce debug output
Also note:
f"{x=}" requires Python 3.8+
Key Takeaways¶
- The
=specifier prints both an expression and its value. - It works with variables, expressions, function calls, and attributes.
- Format specifiers can still be applied after
=. - The output uses
repr()by default. !s,!r, and!acontrol string representation.- The feature is available only in Python 3.8+.
- It provides a concise way to add debugging output.