python闭包函数的作用,python 嵌套函数与闭包
本文主要介绍python函数的高级闭包函数。内部函数使用外部函数的局部变量,外部函数调用内部函数返回闭包的过程。内部函数是闭包函数,可以参考下面的相关介绍。
00-1010闭包函数什么是闭包函数?判断是否是闭包函数\__closure__cell_contents闭包函数的特征闭包函数的意义
目录
闭包函数
如果内函数使用外函数的局部变量,外函数返回内函数的过程叫做闭包,那么里面的内函数就是闭包函数。
#外部函数
定义外部():
#外部函数变量编号
Var=外部函数局部变量
#内部函数inner
内部定义():
#内部函数使用外部函数的变量num
Print(内在函数用途: var )
# outer函数返回使用outer函数的局部变量的内部函数。
返回内部
#返回的结果是内部函数inner,现在inner是闭包函数。
func=outer()
#执行返回的内部函数
Func() #内部函数使用:外部函数局部变量
以下是一个复杂的版本。
内部函数返回函数X和Y,它们是外部函数的内部函数。虽然它们覆盖了原外层函数的局部变量,但这两个函数本质上都是外层函数的布局变量,所以外层函数回归内层函数,内层函数是闭包函数。
Inner返回outer函数的x和y函数,都是使用outer函数的inner函数num3。外层函数返回内层,内层返回x和y,所以伪装成外层函数返回x和y,所以x和y也是闭包函数。
#外部功能
定义外部():
#外部函数的局部变量
x=1
y=2
num3=3
#内部函数x与变量x同名
def x():
#该调用修改了变量num3
非本地num3
num3 *=10
打印(num3)
#内部函数Y与变量Y同名。
定义y():
#该调用修改了变量num3
非本地num3
num3=10
打印(num3)
#内部函数inner
内部定义():
#返回同一级别的函数x y。
返回x,y
#外层函数最后返回内层函数。
返回内部
什么是闭包函数
方法
功能
\__closure__
获取闭包函数使用的局部变量。
单元格内容
获取cell对象中的闭包函数。
判断是否是闭包函数
可以用这个方法来判断一个函数是否是闭包函数,因为闭包函数必须使用外层函数的局部变量。如果它返回None,就意味着这个函数不是闭包函数。如果它返回一个元组,说明它是一个闭包函数,元组中有cell对象。一个单元格对象意味着闭包函数使用外部函数的几个局部变量。
拿上面的版本做测试。
#外部功能
定义外部():
#外部函数的局部变量
x=1
y=2
num3=3
#内部函数x与变量x同名
def x():
#该调用修改了变量num3
非本地num3
num3 *=10
打印(num3)
#内部函数Y与变量Y同名。
定义y():
#该调用修改了变量num3
非本地num3
num3=10
打印(num3)
#内部函数inner
内部定义():
#返回同一级别的函数x y。
返回x,y
#外层函数最后返回内层函数。
返回内部
#执行outer返回的结果是inner。
func=outer() # func==inner
#执行func返回x y函数
a,b=func()
#使用__closure__测试这些函数是否是闭包函数。
打印(外部。__closure__)
打印(功能。__closure__)
打印
(a.__closure__)
print(b.__closure__)
结果:除了外函数outer之外都返回了cell对象,说明inner x y 都是闭包函数
None
(<cell at 0x0000022F246AECA8: function object at 0x0000022F2466C400>, <cell at 0x0000022F247F3558: function object at 0x0000022F24850730>)
(<cell at 0x0000022F245D8708: int object at 0x00000000542280B0>,)
(<cell at 0x0000022F245D8708: int object at 0x00000000542280B0>,)
cell_contents
虽然用__closure__
获取到了闭包函数使用的元素,但是是以cell单元格对象的形式展示的,我们并不能看出这个使用的 元素到底是什么东西,可以使用cell_contents
查看。
# 外函数def outer():
# 外函数的局部变量
x = 1
y = 2
num3 = 3
# 内函数 x 重名变量 x
def x():
# 调用修改了 变量 num3
nonlocal num3
num3 *= 10
print(num3)
# 内函数 y 重名变量y
def y():
# 调用修改了 变量num3
nonlocal num3
num3 += 10
print(num3)
# 内函数inner
def inner():
# 返回了同级内函数 x y
return x, y
# 外函数最终返回了 inner函数
return inner
# 执行outer返回的结果是inner
func = outer() # func == inner
# 使用__closure__返回了闭包函数使用的局部变量
tup = func.__closure__
# 使用 cell_contents 查看这些局部变量都是些什么
res = tup[0].cell_contents
print(res)
res = tup[1].cell_contents
print(res)
结果:可以看到inner 使用的局部变量使用外函数的内函数 x 和 y
None
<function outer.<locals>.x at 0x0000018D5A66C400>
<function outer.<locals>.y at 0x0000018D5A850730>
闭包函数的特点
让我们回忆一下,函数中创建的变量是一个什么变量?是一个局部变量。
局部变量的生命周期是多久?是等局部作用结束之后就会被释放掉。
如果内函数使用了外函数的局部变量,那么这个变量就与闭包函数发生了绑定关系,就延长该变量的生命周期。实际上就是内存给它存储了这个值,暂时不释放。
下面的例子中,我们调用了函数outer并赋予了参数val的值为10,但是outer执行完之后,outer的val并没有被释放,而是被闭包函数inner延长了生命周期,所以val可以一直在inner中按照调用outer函数的时候赋予的值10进行运算。
因为内函数inner使用了外函数outer的变量val,且outer返回了inner,所以inner是一个闭包函数。因为inner是一个闭包函数,当它调用outer的变量val时就会延长val的生命周期,val就不会随着outer的调用结束而被释放
而是存储在了内存当中,当inner再次使用val时,val就会将值赋予inner。
def outer(val):def inner(num):
return val + num
return inner
func = outer(10)
res = func(10)
print(res) # 20
res = func(20)
print(res) # 30
闭包函数的意义
闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装包保护的作用,使外部无法访问。
我们做一个模拟鼠标点击的事件,可以看得出闭包函数封装保护数据的作用。
现在只是一个普通的函数,它无法对我们使用的变量的数据进行保护,在全局中这个数据可以被随意的修改。
# 不使用闭包,当函数中调用全局变量时,外部也可以控制变量# 全局变量
num = 0
# 点击事件
def click_num():
# 每执行一次数值 +1
global num
num += 1
print(num)
# 执行点击事件
click_num() # 1
click_num() # 2
click_num() # 3
# 在全局重新定义了num的值,num的值就被彻底的改变了,但是我们的程序的数据本不该如此。
num = 1231231
click_num() # 1231232
click_num() # 1231233
click_num() # 1231234
现在使用闭包函数对数据进行封装保护,就不能在全局中随意的修改我们使用的数据。
# 我们将需要使用的数据放在外函数中,点击事件作为内函数也放在外函数中,然后作为闭包返回。def clickNum():
# 需要使用的数据
num = 0
# 内函数(真正执行点击事件的函数)
def inner():
# 执行点击事件
nonlocal num
num += 1
print(num)
# 作为闭包返回
return inner
# 返回闭包
click_num = clickNum() # # click_num == inner
# 执行点击事件
click_num() # 1
click_num() # 2
click_num() # 3
# 全局中修改 num 的值
num = 123412341234
# 闭包函数对数据的封装保护起到了作用
click_num() # 4
click_num() # 5
click_num() # 6
到此这篇关于python 函数进阶之闭包函数的文章就介绍到这了,更多相关python 闭包函数内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。