backend / python core / 03_variable_scope.md

Variable Scope in Python

3 interview angles 2 min read source

Variable Scope in Python

Variable scope refers to the context in which a variable is accessible within a program. It determines where a variable can be defined, modified, or accessed.

Types of Variable Scope

1. Local Scope

  • A variable declared inside a function belongs to the local scope of that function.
  • It can only be accessed within the function where it is defined.

2. Enclosing Scope

  • This applies to variables in nested functions.
  • A variable in the enclosing scope of a nested function is accessible inside the nested function but not outside its enclosing function.

3. Global Scope

  • A variable defined outside of any function belongs to the global scope and is accessible anywhere in the program.
  • Use the global keyword to modify a global variable inside a function.

4. Built-in Scope

  • This is the scope of Python’s built-in functions and keywords.
  • These are accessible anywhere in the code unless overridden.

LEGB Rule

Python resolves variable names using the LEGB Rule, which stands for:

  1. Local: Variables defined within a function.
  2. Enclosing: Variables in enclosing functions (for nested functions).
  3. Global: Variables defined at the top level of a script or module.
  4. Built-in: Names in Python’s built-in namespace (e.g., len, print).

Key Points to Remember

  • Local variables are temporary and exist only during the function’s execution.
  • Global variables persist for the program’s duration but should be used sparingly to avoid conflicts.
  • Use the nonlocal keyword to modify variables in the enclosing scope.

def my_function():
    local_var = 10  # Local scope
    print(local_var)

my_function()
# print(local_var)  # This will raise an error (NameError)
def outer_function():
    enclosing_var = "Enclosing Scope"

    def inner_function():
        print(enclosing_var)  # Accessible inside the inner function

    inner_function()

outer_function()
global_var = "Global Scope"

def access_global():
    print(global_var)  # Accessible globally

def modify_global():
    global global_var
    global_var = "Modified Global Scope"

access_global()
modify_global()
print(global_var)  # Output: "Modified Global Scope"
print(len("Python"))  # Built-in function len
def outer_function():
    x = "outer"

    def inner_function():
        nonlocal x
        x = "modified outer"
        print(x)

    inner_function()
    print(x)

outer_function()

Interview angle

  • “What is LEGB?” - Local, Enclosing, Global, Built-in: the order Python searches for a name. Assignment anywhere in a function makes the name local for the entire function, which is why reading it before assignment raises UnboundLocalError rather than falling back to the global.
  • global versus nonlocal?” - global rebinds at module level; nonlocal rebinds in the nearest enclosing function scope. nonlocal is what closures need to mutate captured state.
  • “Why do closures in a loop all capture the same value?” - they capture the variable, not its value at definition time. Bind it with a default argument or functools.partial. See tricky_questions/02_late_binding_closures.md.