闭包的编写套路:
def outer(a,b):
def inner(x):
.......
return ...
return inner
outer称为外函数
inner称为内函数,内函数inner使用了外函数outer的参数a,b。
外函数outer最终的返回值是内函数inner的引用。
闭包是Python实现面向对象的一种方式。
每调用一次外函数outer,就会产生一个对象;
n = outer(4,6)
m = outer(5,3)
n 和 m 就是两个不一样的对象。若是这个函数是用来计算二元一次方程的话,那么 n 和 m 就是两条不一样的直线。
调用不一样对象的内函数就能够对不一样对象进行操做了。
对 n 对象进行操做:
print(n(9)) # 由于outer()函数的返回值是内函数inner的引用 --> 它被赋给了 n 这个变量,因此直接调用 n 就至关于调用了 outer(4,6) 这个外函数里的 inner()
假如这个函数是用来求解二元一次方程的,那么 outer(4,6) 就至关于建立了 4X+6 这条直线(对象),而调用 n(9) 就至关于把 X=9 带入这个式子进行计算,获得的结果就是 42 了。
每次调用 n(?) 都是调用了 outer(4,6)里的 inner(?) ,inner(?) 使用了 outer(4,6)里的参数 4 和 6 。做为内函数是能够任意使用外函数的变量的。
可是,若是要修改外函数的变量的话,有 2 个方法:
1)在修改以前须要用 nonlocal 关键字声明变量,表示须要向上一层变量空间找这个变量。
2)把 闭包变量 改为 可变类型,好比 列表 。
代码实例:
1 def counter(first = 0):
2 cnt = [0]
3 def add_one():
4 cnt[0]+=1
5 return cnt[0]
6 return add_one
7
8 num5 = counter(5)
9 print(num5())
10 print(num5())
11 print(num5())
12 print(num5())
13 print(num5())
运行结果:闭包

是什么将内函数与外函数牢牢联系在一块儿,是外函数的参数。外函数的参数是实现面向对象的本质。不一样的外函数参数建立了不一样的对象。
内函数是能够任意使用外函数的参数和变量的,在上面这个例子中,外函数有一个变量 cnt 和一个参数 first,内函数只使用了 变量 cnt ,那么内函数是怎么对外函数参数产生的对象进行操做的呢?在外函数使用不一样的参数产生多个对象的时候,内函数是如何识别不一样的对象并分别对它们进行操做的呢?
num5 = counter(5)
num6 = counter(6)
num7 = counter(7)
#上面就产生了三个不一样的对象了,它们分别是这样调用内函数的:
num5()
num6()
num7()
#所以答案揭晓:经过将 不一样对象 赋给 不一样的变量(num5,num6,num7),再经过调用这几个变量,就能够实现分别对 不一样的对象 调用内函数了