Quick answer: locals() returns a mapping representing names in the current local scope. Use it for inspection and controlled introspection, but do not rely on modifying the mapping to create or update optimized local variables inside a function; explicit dictionaries are safer.

locals() is a built-in Python function that returns a mapping for the names available in the current local namespace. In everyday code, it is most useful for inspection, debugging, templating, and learning how Python scopes work.
The important rule is simple: use locals() to read the current namespace, not to update normal function variables. Inside functions, generators, and coroutines, Python returns a fresh dictionary of the current local bindings. Changing that dictionary does not reliably change the actual local variables.
Syntax
locals()
locals() takes no arguments. It returns a mapping where each key is a variable name and each value is the object currently bound to that name.
Basic example inside a function
In a function, locals() lets you inspect parameters and variables that have already been assigned.
def describe_order(item, quantity):
status = "ready"
return locals()
print(describe_order("book", 3))
{'item': 'book', 'quantity': 3, 'status': 'ready'}
This is why locals() is handy when debugging a small function. It shows the names in that function’s local namespace at the point where it is called.
Do not use locals() to update local variables
A common mistake is to treat the returned dictionary as if assigning to it will assign to real local variables. That is not how normal function scope should be used.
def demo():
score = 10
namespace = locals()
namespace["score"] = 99
return score, namespace["score"]
print(demo())
(10, 99)
The dictionary changed, but the local variable score did not. If you need to change a variable, assign to the variable directly:
score = 99
If you need a mutable collection of dynamic names, use a normal dictionary that you control. See the guide on adding keys to a Python dictionary for that pattern.

locals() at module level
At the top level of a module, the local namespace and global namespace are the same mapping. That means locals() and globals() refer to the same dictionary.
language = "Python"
print(locals() is globals())
print(locals()["language"])
True
Python
For more examples of the module namespace, read the Python Pool guide to Python globals().
locals() inside a class body
A class body has its own namespace while Python is building the class. Calling locals() inside the class body shows the attributes that have been defined so far.
class Tool:
category = "parser"
snapshot = locals().copy()
print(Tool.snapshot["category"])
parser
This can be useful when learning how class definitions work, but it is rarely needed in ordinary application code.
Checking keys in locals()
Because locals() returns a mapping, you can check whether a name exists with normal dictionary membership syntax.
def has_discount(price, discount=None):
names = locals()
return "discount" in names
print(has_discount(100))
True
Use this for inspection rather than application logic. In production code, it is usually clearer to check the variable directly, such as discount is not None.

locals() with comprehensions
Comprehensions have their own scoping details. In modern Python, calling locals() as part of a list comprehension inside a function includes the containing function’s local names and the comprehension’s iteration variable. Generator expressions behave like nested generator functions.
Most programs do not need locals() inside comprehensions. If you are using it there, you are probably debugging scope behavior or writing introspection code. For normal data transformations, keep the comprehension focused on the values being built. The Python set comprehension guide shows that style.
locals() vs globals() vs vars()
| Function | What it returns | Common use |
|---|---|---|
locals() |
The current local namespace mapping | Inspect names in the current scope |
globals() |
The current module namespace dictionary | Read or intentionally update module-level names |
vars() |
An object’s __dict__, or locals() when called with no argument |
Inspect attributes on modules, classes, and instances |
If you are comparing these functions, also see the Python Pool guides to globals() and vars().
Common mistakes
- Trying to create a function variable with
locals()["name"] = value. Assign to the variable directly or store dynamic names in your own dictionary. - Assuming function
locals()is the same object every time. In optimized scopes such as functions, each call returns a fresh dictionary of current bindings. - Logging
locals()in production. It can expose passwords, tokens, request data, or other sensitive values. - Shadowing built-in names. Avoid variables like
list,dict, orstrwhen exploring namespace dictionaries.
When should you use locals()?
Use locals() when you need to inspect the names available in the current scope, pass a namespace into a template, or understand how Python resolves names while debugging. Avoid it when a normal variable, function argument, object attribute, or dictionary would make the code clearer.
The official Python documentation covers locals(), globals(), vars(), and the language reference section on naming and binding. Those are the best references when you need the exact scope rules.

Conclusion
locals() returns a mapping for the current local namespace. It is useful for inspection, but it is not a clean way to modify local variables inside a function. Use direct assignment for variables, dictionaries for dynamic data, and globals() or vars() only when their specific namespace behavior is what you actually need.
Understand The Current Scope
At module level, locals() and globals() commonly describe the same namespace. Inside a function, locals() represents the function’s local names at the point of the call.
Treat The Mapping As Inspection
The implementation may expose a snapshot-like mapping rather than a live writable variable table. Reading it for debugging is reasonable; writing it is not a dependable assignment mechanism.
Use Explicit Data For Dynamic Names
If a program needs dynamic keys, store them in a dictionary, dataclass, or dedicated object. This makes ownership, validation, and serialization clearer than dynamically inventing local variables.

Compare locals And globals
globals() exposes the module namespace, while locals() follows the current local context. Passing these mappings into a template or evaluator should be treated as a security boundary.
Avoid Leaking Sensitive Values
Local namespaces may contain tokens, file handles, user data, and intermediate objects. Filter what is logged or exposed, especially in error messages and debugging endpoints.
Test Introspection Carefully
Test module and function scopes, nested functions, comprehensions, and values introduced before and after the call. Assert the intended read-only inspection behavior rather than mutation side effects.
The official locals() documentation describes scope and modification behavior. Related Python Pool references include safe logging and tests.
For related introspection work, compare safe diagnostics, scope tests, and explicit dictionaries before changing namespaces.
Frequently Asked Questions
What does locals() return?
It returns a mapping representing the current local symbol table in the scope where it is called.
Can I create local variables by changing locals()?
Do not rely on that behavior; modifying the returned mapping is not a dependable way to change optimized local variables inside a function.
How is locals() different from globals()?
locals() describes the current local namespace, while globals() exposes the module’s global namespace.
When is locals() useful?
It is useful for debugging, introspection, templates, and carefully controlled metaprogramming, but explicit data structures are usually clearer.