Back to Blog
Python

Using Python f-String Debug to Print Variable Names and Values

python f string debug: Learn how the `=` specifier in Python f-strings prints variable names and values for faster debugging, with formatting and compatibility notes.

Pythonf-stringsdebuggingstring formattingPython 3.8
Code editor showing a Python f-string debug line with variable name and value displayed

When you need to inspect a variable's value during development, print(f"x = {x}") is common, but Python 3.8 introduced a more concise form: print(f"{x=}"). This f-string debug syntax automatically includes the variable name and its value, reducing repetitive typing and making temporary debug lines easier to read. The python f string debug feature works by appending an equals sign inside the replacement field, and it also respects format specifiers for additional control.

The = Specifier in f-Strings

The = specifier tells Python to print the expression text, an equals sign, and then the repr of the value. For a simple variable:

name = "Ada" print(f"{name=}") # Output: name='Ada'

The expression text is exactly what appears inside the braces, so if you use a more complex expression, that expression is printed literally:

a = 3 b = 4 print(f"{a + b=}") # Output: a + b=7

This works with any valid Python expression, including function calls and attribute access, making it a flexible tool for quick inspection.

Formatting the Debug Output

The = specifier composes with the existing f-string format specification. Place the format spec after the equals sign, separated by a colon:

pi = 3.14159 print(f"{pi=:.2f}") # Output: pi=3.14

This is especially useful when you need to control precision, padding, or alignment while still preserving the variable name. The syntax is {expression=:format_spec}. Without a format spec, the value is shown using repr(), which for strings includes quotes and for other objects uses their __repr__ method.

Debugging Multiple Variables in One Expression

You can include several debug fields in a single f-string, and Python inserts spaces between them exactly as written:

x = 10 y = 20 print(f"{x=} {y=}") # Output: x=10 y=20

If you need a separator like a comma, add it explicitly:

print(f"{x=}, {y=}") # Output: x=10, y=20

This keeps the output readable and avoids multiple print calls, which is convenient when tracing several related values in a loop or a function.

How the Debug Output Is Constructed

When you write f"{expr=}", Python internally converts the expression to its source code string, appends =, and then calls repr() on the evaluated result. This means the printed representation follows __repr__, not __str__. For example, a datetime object shows its full repr, which may be more verbose than a formatted date string. If you want a different representation, use a format spec or explicitly call str() inside the expression:

import datetime now = datetime.datetime(2024, 1, 1) print(f"{now=}") # Output: now=datetime.datetime(2024, 1, 1, 0, 0) print(f"{now:%Y-%m-%d=}") # Output: now:2024-01-01=2024-01-01 00:00:00

Note that when a format spec is present, the value is formatted using that spec, and the = is placed after the expression text but before the colon. The output includes the format spec itself, which can be surprising if you are not expecting it.

Python Version and Compatibility

The = specifier for f-strings was introduced in Python 3.8. If you are working in an environment that uses Python 3.7 or earlier, this syntax raises a SyntaxError. For code that must run on older versions, you need to fall back to the traditional print(f"x = {x}") or use the format method. Most modern Python projects are on 3.8+, but it is worth checking the runtime version if you see unexpected errors. The feature is part of the language specification, so it works in CPython, PyPy, and other implementations that support Python 3.8+.

Performance and Production Considerations

The debug syntax has a negligible runtime cost compared to a regular f-string because it adds only the expression source text to the format string. However, using it in production code is rarely appropriate. Debug output often leaks internal variable names and can clutter logs. The feature is designed for interactive development and temporary instrumentation. If you need structured logging, use the logging module with appropriate formatters instead. Also, be aware that the expression is evaluated once, just like any f-string field, so there is no double evaluation or hidden side effect.

Common Mistakes and Edge Cases

One common mistake is using = with an expression that contains spaces, such as f"{a + b =}". This is valid, but the output will include the spaces exactly as written: a + b =7. If you want a cleaner output, avoid spaces around the equals sign in the expression. Another edge case is using = with a tuple or list literal; the repr will show the full structure, which may be long. For example:

items = [1, 2, 3] print(f"{items=}") # Output: items=[1, 2, 3]

If you need to truncate long output, you can combine the = specifier with a format spec that limits width, but the repr itself is not truncated. For objects with expensive __repr__, the debug call will invoke that method, so be cautious when debugging large data structures in a tight loop. Finally, remember that the expression text is taken literally from the source code, so comments inside the expression are not allowed, and line breaks must be handled with backslashes or parentheses if the expression spans multiple lines.

python f string debug: Practical Usage and Code Examples | RYUSLOG DEV