闭包:一个持有外部环境变量的函数就是闭包;闭包是一个能够访问其他函数作用域的函数
'''
简化写法
'''
def multipliers():
return [lambda x: i * x for i in range(4)]
print([m(2) for m in multipliers()])
'''
拆分一下
'''
# 拆分 multipliers()第一步:
def multipliers():
ls = [] #列表表达是拆分方法
for i in range(4): #lambda x:i*x 调用了上一层函数multipliers()的局部命名空间的变量i
ret = lambda x: i * x #这里还可以拆分
ls.append(ret)
print(i) #打印3
return ls #返回的是局部变量,不是闭包
# 拆分 multipliers()第二步:
def multipliers():
ls = []
for i in range(4):
def inner(x): #定义 inner函数使用了multipliers()的局部命名空间的变量i
return x*i
ret = inner
ls.append(ret)
print(i) #打印3
return ls #返回了函数
#加一个便于理解的代码
for i in range(4):
pass
print(i) #打印3
ret = []
for m in multipliers():
ret.append(m(2))
print (ret) # 打印 [6, 6, 6, 6]
print(multipliers()[0](2)) #打印6
'''
从python解释器开始执行之后,就在内存中开辟了一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。
但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。
等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,
而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
'''
'''
只有当调用闭包函数的时候它才会去引用外层函数的变量,因为在调用闭包函数之前,闭包内部的命名空间还不存在。
所以multipliers的里面存放了四个函数,当去调用的时候,for i in range(4)这个循环已经执行完毕,此时的i已经是3了,新开辟的命名空间里面的i就是3了
'''
顺便加一个装饰器
def wrapper(func):
def inner(request):
print('start wrapper')
r = func(request) #inner函数使用了外部的func参数,所以也是一个闭包
print('end wrapper')
return r
return inner