为什么要用闭包?
# 问题:y=kx+b,y=ax^2+bx+c
# 以y=kx+b为例,请计算一条线上的过个点 即 给x值 计算出y值
# 第1种
k=1
b=2
x=0
y=k*x+b
# 缺点:如果需要多次计算,那么就得写多次y=k*x+b的式子
print('-'*50)
# 第2种
def line_2(k,b,x):
y = k * x + b
print(y)
line_2(1,2,0)
line_2(1,2,1)
line_2(1,2,2)
# 缺点:如果需要多次计算这条线上的Y值,那么每次都需要传递kb的值,很麻烦
print('-'*50)
# 第3种 全局变量
k=1
b=2
def line_3(x):
y = k * x + b
print(y)
line_3(0)
line_3(1)
line_3(2)
k=11
b=22
line_3(0)
line_3(1)
line_3(2)
# 缺点:如果需要计算多条线上的Y值,那么需要每次对全局变量进行修改,很麻烦
print('-'*50)
# 第4种 缺省参数
def line_4(x,k=1,b=2):
y = k * x + b
print(y)
line_4(0)
line_4(1)
line_4(2)
line_4(0,k=11,b=22)
line_4(1,k=11,b=22)
line_4(2,k=11,b=22)
# 优点:比全局变量的方式好在kb是函数line_4的一部分,而不是全局变量,因为全局变量可以任意的被其他函数所修改
# 缺点:如果需要计算多条线上的Y值,那么需要再电泳的时候进行传递参数,很麻烦
print('-'*50)
# 第5种 实例对象
class line_5(object):
def __init__(self,k,b):
self.k=k
self.b=b
def __call__(self,x):
print(self.k*x+self.b)
line_5_1 = line_5(1,2)
line_5_1(0)
line_5_1(1)
line_5_1(2)
line_5_2 = line_5(11,22)
line_5_2(0)
line_5_2(1)
line_5_2(2)
# 缺点: 为了计算多天线上的y值,所需要保存多个kb值,因此用了很多个实例对象,浪费内存资源
print('-'*50)
# 第6种 闭包
def line_6(k,b):
def create_y(x):
y = k * x + b
print(y)
return create_y
line_6_1 = line_6(1,2)
line_6_1(0)
line_6_1(1)
line_6_1(2)
line_6_2 = line_6(11,22)
line_6_2(0)
line_6_2(1)
line_6_2(2)
什么是闭包?
# 闭包是由两个函数嵌套定义,内部函数里面用到了外部函数里面的变量值,那么这个变量(变量值)加上内部还是里面的代码组成的代码块,组成了一个新的内存空间,我们把这个空间叫做闭包。
# 闭包 = 函数+环境变量(在函数定义的时候定义,它不是全局变量,这个环境变量一定要被内部函数调用才算是闭包)
def curve_pre():
# a是环境变量
a = 25
def curve(x):
return a*x*x
return curve
f = curve_pre()
g= f(2)
print(g,'\n')
# 闭包的经典误区
def f1():
a = 10
def f2():
# 此时如果a被重新定义将不构成闭包
a = 20
print(a)
print(a) #10
f2() #20
print(a) #10
f1()
# 正确写法
def f1():
a = 10
def f2():
c = a*10
return f2
h = f1()
print(h.__closure__)
# 闭包实例 走路 能记忆上一次的状态
origin = 0
def factory(pos):
def go(step):
# 不是本地局部变量
nonlocal pos
new_pos = pos + step
pos = new_pos
return new_pos
return go
tourist = factory(origin)
print(tourist(2))
print(tourist(3))
print(tourist(6))