Python resolves names with the LEGB rule, and inner functions can close over variables from the function that created them.
LEGB: where a name is looked up
Local
Names assigned inside the current function.
Enclosing
Locals of any enclosing (outer) functions.
Global
Names at the top level of the module.
Built-in
len,print,range, … from thebuiltinsmodule.
x = "global"
def outer():
x = "enclosing"
def inner():
return x # found in the enclosing scope
return inner()
print(outer(), x) # enclosing globalglobal and nonlocal
Assigning to a name makes it local to that function. To rebind an outer name, declare it first.
count = 0
def bump():
global count
count += 1
def make_counter():
n = 0
def inc():
nonlocal n # rebinding the enclosing variable
n += 1
return n
return inc
bump(); bump()
c = make_counter()
c(); c()
print(count, c()) # 2 3Closures
def multiplier(k):
def times(x):
return x * k # k is captured
return times
double, triple = multiplier(2), multiplier(3)
print(double(5), triple(5)) # 10 15
print(double.__closure__[0].cell_contents) # 2Late binding in loops
# Every lambda sees the final value of i:
fns = [lambda: i for i in range(3)]
print([f() for f in fns]) # [2, 2, 2]
# A default argument captures each value at definition time:
fns = [lambda i=i: i for i in range(3)]
print([f() for f in fns]) # [0, 1, 2]