A closure is a function that retains the bindings of the free variables that exist when the function is defined, i.e. it would maintain a refernce to the free variables that can be used when the function is invoked later.
def func(x):
= 100
y def nested_func(z):
return x + y + z
return nested_func
= func(10)
f print(f.__closure__) #=> (<cell at 0x7fd10dc26830: int object at 0x7fd108a00210>,
#=> <cell at 0x7fd10d7abe50: int object at 0x7fd108a00d50>)
print(f.__code__.co_freevars) #=> ('x', 'y')
10) #=> 120 f(
x
and y
are free variables here. Each object f.__closure__
corresponds to a name in the f.__code__.co_freevars
.
This is in some way similar to decorators where the decorated function is nothing but the nested function, which can be written in the following form:
def func(x):
def decorator_func(func):
= 100
y def wrapper_func(z):
return func(z) + x + y
return wrapper_func
return decorator_func
@func(10)
def nested_func(z):
return z
10) #=> 120 nested_func(