locals()

locals()
Returns: dict · Added in v3.0 · Updated March 13, 2026 · Built-in Functions
built-in namespace local dictionary introspection

The locals() function returns a dictionary containing the current local namespace. This dictionary holds all local variables, parameters, and other symbols defined within the current scope. Unlike globals(), which returns module-level variables, locals() captures variables in the immediate enclosing scope — typically the current function or module level.

Syntax

locals()

Parameters

ParameterTypeDefaultDescription
(none)This function takes no arguments.

Returns: A dict representing the current local symbol table. At module level, this is the same as globals().

Examples

Viewing local variables in a function

def calculate_stats(numbers):
    """Calculate and display statistics."""
    total = sum(numbers)
    count = len(numbers)
    average = total / count
    
    # Inspect local variables
    local_vars = locals()
    print(f"Local variables: {local_vars}")
    # {'numbers': [1, 2, 3, 4, 5], 'total': 15, 'count': 5, 'average': 3.0}
    
    return average

result = calculate_stats([1, 2, 3, 4, 5])
# Local variables: {'numbers': [1, 2, 3, 4, 5], 'total': 15, 'count': 5, 'average': 3.0}

Accessing local variables dynamically

def process_data(name, value):
    """Process data using local variables."""
    result = f"{name}: {value}"
    status = "completed"
    
    # Access local variable by name
    print(locals()['name'])
    # process_data
    
    # Modify via locals() - only works inside function, not at module level
    return result

output = process_data("test", 42)
# test

Capturing locals for later use

def create_snapshot():
    """Capture current local state."""
    x = 10
    y = 20
    z = "hello"
    
    # Return copy of local namespace
    return locals().copy()

snapshot = create_snapshot()
print(snapshot)
# {'x': 10, 'y': 20, 'z': 'hello'}

# Original locals still exist
print(x)  # NameError: name 'x' is not defined

Using with debugging

def inspect_locals():
    """Debug helper to inspect all local variables."""
    for name, value in locals().items():
        print(f"  {name} = {value!r}")
    
    print(f"Total locals: {len(locals())}")

def example_function(a, b):
    x = a * 2
    y = b + 10
    message = "Calculation complete"
    
    print("Local variables:")
    inspect_locals()
    
    return x + y

example_function(5, 3)
# Local variables:
#   a = 5
#   b = 3
#   x = 10
#   y = 13
#   message = 'Calculation complete'
# Total locals: 5

Comparing locals() and globals()

module_var = "I'm global"

def compare_scopes():
    local_var = "I'm local"
    
    print("--- locals() ---")
    local_dict = locals()
    print(f"'local_var' in locals: {'local_var' in local_dict}")
    print(f"'module_var' in locals: {'module_var' in local_dict}")
    
    print("\n--- globals() ---")
    global_dict = globals()
    print(f"'local_var' in globals: {'local_var' in global_dict}")
    print(f"'module_var' in globals: {'module_var' in global_dict}")

compare_scopes()
# --- locals() ---
# 'local_var' in locals: True
# 'module_var' in locals: True (at module level scope, both merge)
# 
# --- globals() ---
# 'local_var' in globals: False
# 'module_var' in globals: True

Common Patterns

Conditional variable inspection

def complex_function(data, debug=False):
    """Example of conditional debugging with locals."""
    processed = []
    
    for item in data:
        transformed = item * 2
        processed.append(transformed)
    
    if debug:
        print("Debug: locals() at end of loop")
        for k, v in locals().items():
            if not k.startswith('_'):
                print(f"  {k}: {v}")
    
    return processed

result = complex_function([1, 2, 3], debug=True)
# Debug: locals() at end of loop
#   data: [1, 2, 3]
#   processed: [2, 4, 6]
#   item: 3
#   transformed: 6

Snapshot testing

def capture_state():
    """Capture state for testing purposes."""
    user_name = "Alice"
    session_id = "abc123"
    permissions = ["read", "write"]
    
    return {
        'state': locals().copy(),
        'timestamp': '2026-03-06'
    }

state = capture_state()
print(state)
# {'state': {'user_name': 'Alice', 'session_id': 'abc123', 'permissions': ['read', 'write']}, 'timestamp': '2026-03-06'}

Default values from locals

def process_with_defaults(required_param, optional_param=None):
    """Use locals() to build parameter dict."""
    # Extract all parameters as a dictionary
    params = {k: v for k, v in locals().items() if k != 'optional_param' or v is not None}
    print(params)
    
    return params

process_with_defaults("test")
# {'required_param': 'test'}

process_with_defaults("test", "optional")
# {'required_param': 'test', 'optional_param': 'optional'}

Important Behaviors

At module level, locals() == globals()

# At the module (top-level) scope, locals() returns the same dictionary as globals()
print(locals() is globals())  # True at module level

Returns live snapshot

# locals() returns a snapshot that may not reflect later modifications
def example():
    x = 1
    snapshot = locals()
    x = 2
    print(snapshot['x'])  # Still shows 1, not updated!
    
    # To get updated values, call locals() again
    print(locals()['x'])  # Shows 2

Does not include nonlocal variables

def outer():
    outer_var = "outer"
    
    def inner():
        # locals() in inner does NOT include outer_var
        # That requires using nonlocal or closure inspection
        inner_var = "inner"
        print(f"Inner locals: {locals()}")
        # {'inner_var': 'inner'}
    
    inner()

outer()

Errors

No parameters

# locals() does not accept any arguments
locals('invalid')
# TypeError: locals() takes no arguments (0 positional arguments)

Modifications are unreliable

# Modifying the returned dict does NOT modify actual local variables
def test():
    x = 10
    locals()['x'] = 20
    print(x)  # Still prints 10 - modification has no effect!

See Also