How to Print th Name of a Variable in Python
In Python, there is no direct, built-in function to get the name of a variable as a string. This is because a variable is just a name or "label" that refers to an object in memory, and a single object can have multiple names pointing to it. Therefore, the concept of an object's "one true name" doesn't exist.
However, for debugging and logging purposes, it is often useful to display the name of a variable alongside its value. This guide will cover the modern, Pythonic way to do this using f-strings, as well as older, more complex introspection methods and their significant limitations.
Understanding the Challenge: Names are Labels, Not Properties
Before diving into solutions, it's crucial to understand why this is a non-trivial task. In Python, a variable is not an object that contains a name. Instead, the name is a reference in a "namespace" that points to an object.
a = [1, 2, 3]
b = a # 'a' and 'b' now point to the exact same list object in memory.
If you had a hypothetical get_name() function, what should get_name(b) return? 'a' or 'b'? Because of this ambiguity, Python does not provide a simple tool for this. The solutions below are workarounds for specific use cases like debugging.
Method 1: Using f-string Debugging (Python 3.8+)
Introduced in Python 3.8, an enhancement to f-strings provides the best, most direct, and safest way to display a variable's name and its value for debugging.
Example of problem: you want to print a variable's name and its value without typing them both out.
name = "Tom"
# Repetitive code:
print(f"name = {name}")
Solution: simply add an equals sign (=) inside the curly braces of an f-string.
name = "Tom"
# ✅ Correct: Use the f-string self-documenting expression.
print(f"{name=}")
# You can even include whitespace for readability.
age = 30
print(f"{age = }")
Output:
name='Tom'
age = 30
If you need only the variable name as a string, you can build on this trick by splitting the resulting string.
name = "Tom"
variable_name_str = f"{name=}".split('=')[0]
print(variable_name_str)
Output:
name
Method 2: Introspection with globals() and locals()
For older Python versions or more advanced use cases, you can manually search through the dictionaries of defined variables returned by the globals() and locals() functions. This is a "brute-force" method that comes with significant caveats.
Example of problem: you need a function that can programmatically find the name of a variable passed to it.
Solution: the following function iterates through the global namespace to find a name that points to the given object.
def get_variable_name(variable):
# Get the dictionary of global variables.
global_vars = globals()
# Find the first name that matches the variable's object ID.
for name, value in global_vars.items():
if id(value) == id(variable):
return name
return None
first_variable = "A"
my_pet = "Leo"
print(f"The name of the variable is: '{get_variable_name(first_variable)}'")
print(f"The name of the variable is: '{get_variable_name(my_pet)}'")
Output:
The name of the variable is: 'first_variable'
The name of the variable is: 'my_pet'
This function uses id() to compare object identity, which is more reliable than comparing by value (==). It also only works reliably for global variables. Using locals() inside a function will typically just return the name of the function's parameter.
The Major Limitations of Introspection
The globals()/locals() introspection method is fragile and should be avoided in production code for several reasons:
-
It fails with duplicate values: If multiple variables point to the same object or have the same value, the function will return the first name it finds, which may not be the one you expect.
a = 10
b = 10
print(get_variable_name(b)) # Might return 'a' or 'b', it's unpredictable! -
It is slow: Searching through the entire namespace dictionary is inefficient.
-
Scope issues: It is difficult to make this work reliably across different scopes (e.g., inside functions or classes).
Conclusion
| Method | Best For | Limitations |
|---|---|---|
f-string Debugging (f"{var=}") | Debugging and logging. This is the recommended, modern approach. | Requires Python 3.8+. Not a general-purpose function for retrieving a name programmatically. |
Introspection (globals()) | Advanced metaprogramming or specific legacy use cases where the limitations are understood and acceptable. | Unreliable with duplicate values, slow, and complex scope behavior. Not recommended for general use. |
For the vast majority of cases where you need to see a variable's name, the problem is one of debugging. The f-string debugging syntax (f"{variable=}") was created for this exact purpose and is the correct and most Pythonic tool for the job.