1. 定义:
内层函数使用了外层函数作用域的变量(属于E区变量),则称内部函数为闭包。简单说就是:
- 外层函数里面定义了内层函数
- 内层函数引用了外层函数的变量(E区变量)
#这不是闭包,只是函数的嵌套
def fun1():
def fun2():
print("fun2
")
return fun2 #这是fun1()的返回值
ret = fun1() #得到fun1.fun2,即fun2
print(ret,'
')
ret() #等价于执行:fun2()
#这才是闭包
def test(number):
#在函数内部再定义一个函数, 并且这个函数用到了外边函数的变量
def test_in(number_in):
print("in test_in 函数, number_in is %d" % number_in)
return number+number_in #其实这里返回的就是闭包的结果
return test_in
ret = test(10) #传入给自由变量number {属于E区}
print(ret,'
')
sum = ret(20) #传给number_in,{属于L区}
print(sum)
这里的numnber称之为自由变量。从作用域讲,它是E区变量,按理说离开了test()就会消亡。可是在闭包里,解释器把number封装进闭包里(也就是封装进入tets_in),所以延长了number的生命周期(离开了test()继续存在)。
2. 应用:
#不要闭包实现f(x) = a*x+b
def line_1(a,b,x):
return a*x+b
y1,y2,y3 = line_1(1,1,11),line_1(1,1,22),line_1(1,1,33)#其实这三次都是用到了一条直线y=x+1,只是传入x不同。
print(y1, ',', y2, ',', y3, '
')
#用闭包实现:先固定一根直线,再传入不同的x获得不同y
def lien_config(a,b): #外函数直接返回一条直线
def line(x): #内函数才是拿这条直线解析式来根据x秋f(x)
return a*x+b
return line
line = lien_config(1,1) #确定了一条直线,后面反复重用
y1,y2,y3 = line(11), line(22), line(33) #调用简化了不少
print(y1, ',', y2, ',', y3, '
')