Decorators are an example of closures. For example,
def decorate(f):
def wrapped_function():
print("Function is being called")
f()
print("Function call is finished")
return wrapped_function
@decorate
def my_function():
print("Hello world")
my_function()
The function wrapped_function
is a closure, because it retains access to the variables in its scope--in particular, the parameter f, the original function. Closures are what allow you to access it.
Closures also allow you to retain state across calls of a function, without having to resort to a class:
def make_counter():
next_value = 0
def return_next_value():
nonlocal next_value
val = next_value
next_value += 1
return val
return return_next_value
my_first_counter = make_counter()
my_second_counter = make_counter()
print(my_first_counter())
print(my_second_counter())
print(my_first_counter())
print(my_second_counter())
print(my_first_counter())
print(my_second_counter())
Also, bound methods are technically closures (though they're probably implemented differently). Bound methods are class member functions with their class baked in:
import sys
w = sys.stdout.write
w("Hello\n")
w
is essentially a closure with a reference to the sys.stdout
object.
Finally, I havn't read that book, but a quick read of the chapter you linked and I'm very unimpressed--it's so horribly roundabout that it's useless as an explanation of closures.