Python by Example

Variables

Variables in Python are name bindings. Understand multiple assignment, LEGB scope, and the UnboundLocalError trap.

Variables in Python are name bindings, not declarations. An assignment x = 1 creates a name x that points to the integer 1; re-assigning x = 2 rebinds the name to a different object. The original object is unchanged, and Python's garbage collector reclaims it if no other names point to it.

Simple assignment, multiple assignment on one line, and in-place swap all work without a temporary variable.

x = 10
a, b = 1, 2        # multiple assignment
a, b = b, a        # swap without a temp variable
 
print(a, b)        # 2 1

When a function reads a variable, Python searches scopes in LEGB order: Local, Enclosing, Global, Built-in. A function can read an outer variable without any extra keyword.

x = "global"
 
def show():
    print(x)   # reads the global x - no keyword needed
 
show()         # global

The UnboundLocalError trap: if a function assigns to a name anywhere in its body, Python treats that name as local for the entire function, even before the assignment line. Reading it before the assignment raises UnboundLocalError. Use nonlocal (for a name in an enclosing function) or global (for a module-level name) when a rebinding is intentional.

count = 0
 
def broken():
    print(count)  # UnboundLocalError! assignment below makes count local
    count = count + 1
 
def fixed():
    global count
    print(count)  # 0 - now unambiguously the global
    count = count + 1

In production

Python rebinds names; it does not declare them. A function that assigns to x shadows any outer x for the entire function body, even before the assignment line - reading it earlier raises UnboundLocalError. Reach for nonlocal only when closure state genuinely belongs to the enclosing function; class state belongs on self.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free