Complete guide to Python's locals function covering namespace inspection, variable access, and practical examples.
Last modified April 11, 2025
This comprehensive guide explores Python’s locals function, which returns a dictionary representing the current local symbol table. We’ll cover basic usage, practical applications, and common patterns.
The locals() function returns a dictionary of the current local symbol table. In function blocks, this includes local variables. At module level, it’s same as globals().
Key characteristics: returns a mutable dictionary that reflects current local variables. Changes to the dictionary may not affect local variables. Useful for debugging and dynamic variable access.
Here’s simple usage showing how locals() captures local variables in different scopes. This demonstrates its basic behavior.
basic_locals.py
def show_locals(): x = 10 y = “hello” print(locals())
show_locals() # {‘x’: 10, ‘y’: ‘hello’}
a = 1 b = 2 print(locals()) # Includes a, b and many other entries
This example shows locals() inside a function and at module level. Inside functions, it only shows local variables. At module level, it shows all global symbols.
The module-level output will be large because it includes all imported names and special variables like name.
While possible, dynamically creating variables using locals() is discouraged. This example shows why it often doesn’t work as expected.
dynamic_vars.py
def create_vars(): lcls = locals() lcls[’new_var’] = 42 print(new_var) # NameError: name ’new_var’ is not defined
try: create_vars() except NameError as e: print(f"Error: {e}")
This demonstrates that modifying the locals dictionary doesn’t actually create new local variables in function scope. The dictionary is a copy in functions.
At module level, modifying locals() can work but is still not recommended due to unclear behavior and maintainability issues.
locals() is often used as a debugging tool to inspect current variables. This example shows a practical debugging scenario.
debugging.py
def complex_calculation(a, b): temp1 = a * 2 temp2 = b ** 3 result = temp1 + temp2
# Debug print
print("Variables at checkpoint:", locals())
return result
print(complex_calculation(3, 4)) # Variables: {‘a’: 3, ‘b’: 4, …}
This shows how locals() can help debug complex functions by displaying all local variables at a specific point in execution.
The output includes function parameters, temporary variables, and the result variable, giving a complete picture of the function’s state.
locals() can simplify string formatting by automatically using local variables. This example demonstrates this pattern.
formatting.py
def format_user(name, age, city): message = “{name} is {age} years old and lives in {city}".format(**locals()) return message
print(format_user(“Alice”, 30, “New York”))
This technique uses the local variables dictionary to provide values for string formatting. It’s concise but can make code less explicit about its inputs.
While convenient, this approach can become unclear with many variables or when variables are modified before formatting.
locals() behaves differently in class definitions than in functions. This example explores its behavior in class scope.
class_scope.py
class MyClass: class_var = “shared”
def __init__(self, instance_var):
self.instance_var = instance_var
@classmethod
def show_locals(cls):
print("Class method locals:", locals())
def show_instance_locals(self):
print("Instance method locals:", locals())
print(“Class definition locals:”, locals().keys()) MyClass.show_locals() obj = MyClass(“unique”) obj.show_instance_locals()
This demonstrates that during class definition, locals() shows the class namespace. In methods, it shows the method’s local variables.
The class method’s locals include cls, while the instance method includes self and any local variables.
Debugging: Use for quick inspection of local variables
Avoid modification: Don’t rely on modifying locals() to create variables
String formatting: Can be useful but may reduce clarity
Scope awareness: Understand behavior differences in functions/classes
Alternatives: Consider explicit dictionaries for dynamic cases
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.