locals()

The local scope's namespace — but the semantics change with context, and function locals are often a SNAPSHOT.

Built-in functionPython 1.0+
Common call
locals()
Returns
the current local namespace — semantics depend on context
Replaces
the CPython "get the current frame's locals" internal API
Watch out
in a function, mutating locals() does NOT change the actual locals — it is a snapshot
locals()
dict

Common patterns

Format an f-string from a dict of local values
Handy for logging when there are many locals to include.
def process(a, b, c):
    ...
    log.debug("state: %s", locals())
Build a dict from local variables
A quick way to package up a set of related computed values.
def compute(x, y):
    total = x + y
    diff = x - y
    return {k: v for k, v in locals().items() if not k.startswith("_")}
String template interpolation
string.Template can substitute names from a dict of locals.
from string import Template
t = Template("Hello $name, age $age")
t.substitute(**locals())
Prefer explicit — locals() is not for writing
Assigning to locals()[name] does NOT create a local variable in a function.
# WRONG: locals()["x"] = 1
# RIGHT: use exec() sparingly, or just do x = 1

Examples

1. Module level
x = 1 locals() == globals()
Returns
True # same dict at module level
2. Function locals
def f(): a = 1 b = 2 return locals()
Returns
{'a': 1, 'b': 2}
3. Not live
def f(): x = 1 locals()["x"] = 99 return x
Returns
1 # unchanged; snapshot
4. Class body
class C: x = 1 print(locals())
Returns
{'__module__': '__main__', 'x': 1, ...}
5. Args + locals
def f(a, b): c = a + b return locals()
Returns
{'a': 1, 'b': 2, 'c': 3}

Pitfalls

1. In a function, locals() is a SNAPSHOT — not live
The single most important locals() detail. Inside a function, locals() returns a dict that Python populated from the frame — but WRITING to it does not affect the frame's actual variables. Every call gives a fresh snapshot.
Write not seen
def f():
    x = 1
    locals()["x"] = 99
    return x
1 # x still 1
Just assign
def f():
    x = 99
    return x
99
2. At module level, locals() IS globals()
They return the same dict object. `locals() is globals()` is True in a module or REPL — the difference only appears in functions and class bodies.
Assumed different
# at module level
locals() is globals()
True
Different in functions
def f(): return locals() is globals()
False
3. Class body: developing attributes
Inside a class body (during class creation), locals() gives the class attributes as they are being defined. After class creation, this dict becomes the class __dict__.
Different times
class C:
    x = 1
    print(locals())   # x already there
{'x': 1, '__module__': ..., ...}
Same as C.__dict__ post-creation
vars(C)
similar contents
4. CPython optimizes function locals — do not rely on order
The order of function locals in the returned dict is an implementation detail. Newer CPython versions may reorder or skip locals that were optimized away.
Order assumption
list(locals())   # order matters?
implementation-dependent
Do not rely on order
sorted(locals())
stable

When to use

Use it
  • Debug output: `log.debug("state: %s", locals())`
  • String template substitution (`Template.substitute(**locals())`)
  • Introspection during test setup or REPL exploration
  • Class body introspection during metaclass work
Reach for something else
  • Writing to function locals — snapshots, not live
  • Dynamic name creation → use dict variables or explicit assignments
  • Cross-function state — pass arguments, do not rummage in locals
  • Anything requiring guaranteed live semantics in a function

Notes

Complexity
O(n) in the number of local variables — snapshot construction
Return
A dict; at module level it IS globals(), inside a function it is a fresh snapshot
CPython impl
Python/bltinmodule.c :: builtin_locals — calls PyEval_GetLocals
Memory
Allocates a snapshot dict in function contexts
Thread-safe
Yes for the returned snapshot

FAQ

Inside a function, locals() is a snapshot of the function's local variables; globals() is the enclosing module's namespace. Inside a class body, locals() is the developing class attributes. At module level, they are the same dict.

History

1.0
locals() has been a builtin since Python 1.0.
3.13
PEP 667 (draft/discussed) proposals to make function locals writable via locals(); not yet accepted.