闭包函数
互相嵌套的两个函数,如果内函数使用了外函数的局部变量
并且外函数把内函数返回出来的过程,叫做闭包
里面的内函数叫做闭包函数
是不是闭包?
1.内函数用了外函数的那个局部变量
2.外函数返回内函数
1.基本语法形式
def zhaoshenyang_family():
father = "马云"
def hobby():
print("我对钱没有一丝丝的兴趣,我不看重钱,这是我爸爸{}说的".format(father))
return hobby
func = zhaoshenyang_family()
func()
print("<==1==>")
判断闭包:
tup = func.__closure__ #返回元祖对象
print(tup[0].cell_contents) # 马云
print(tup)
2.闭包的复杂形式
def zhaowanli_family():
gege = "王思聪"
didi = "鞋王,高振宁"
money = 1000
def gege_hobby():
nonlocal money
money -= 500
print("我交朋友不在乎他有没有钱,反正都没有我有钱.我就喜欢交女朋友... 钱物还剩下{}".format(money))
def didi_hobby():
nonlocal money
money -= 400
print("家里有鞋柜,各式各样的奢侈鞋,一双大概20~30万,钱物还剩下{}".format(money))
def big_master():
return [gege_hobby,didi_hobby]
return big_master
func = zhaowanli_family()
print(func)
lst = func()
print(lst)
# 获取哥哥函数
gege = lst[0]
gege()
# 获取弟弟函数
didi = lst[1]
didi()
首先,big_master是闭包函数,然而,gege_hobby和didi_hobby 是通过big_master间接返回出去的,所以它们俩也是闭包函数
3.使用 closure , cell_contents 判定闭包
通过返回的函数.__closure__返回的元祖中有值,就是个闭包,如下图
“”“如果返回的元组中有数据说明是闭包,谁的生命周期被延长就打印谁”“”
tup = func.__closure__
print(tup)
接着往下探索,gege_hobby是闭包函数,里面有两个变量被调用,gege和money。谁的生命周期被延长,元祖中放的是谁。如果变量被修改,打印出来是修改后的内容
#先获取第一个单元格 cell_contents获取对象中的内容
func1 = tup[0].cell_contents
cell_contents获取对象中的内容,获取到didi_hobby函数对象
可以直接调用didi_hobby这个函数
如果不是闭包函数:分两种
1.没有返回内部函数,打印func.__closure__ 报错
2.内部函数没使用外部函数的变量,打印出None
正常的闭包函数打印
print("<11111>")
"""打印闭包函数didi_hobby中,生命周期被延长的属性"""
print(func1.__closure__[0].cell_contents)
func1()
# 在获取第二个单元格 cell_contents获取对象中的内容
func2 = tup[1].cell_contents
print("<22222>")
"""打印闭包函数gege_hobby中,生命周期被延长的属性"""
print(func2.__closure__[0].cell_contents)
func2()
闭包特点
特点:在闭包函数中,内函数使用了外函数的局部变量,
该变量会与内函数发生绑定,延长该变量的生命周期,
持续到脚本执行结束.
def outer(val):
def inner(num):
return val + num
return inner
func = outer(10)
res = func(15)
print(res)
闭包的意义
全局变量的作用域大,容易被篡改
num = 0
def click_num():
global num
num += 1 # num = num + 1
print(num)
click_num()
click_num()
click_num()
num = 100
click_num()
click_num()
全局变量一直在被修改
#改造,用闭包来实现
“”"
闭包的意义:
闭包可以优先使用外函数中的变量, 并对闭包中的值起到了封装保护的作用. 外部无法访问.
“”"
def outer():
x = 0
def click_num():
nonlocal x
x += 1
print(x)
return click_num
click_num = outer()
click_num()
click_num()
click_num()
x = 100
click_num()
click_num()
这样,即使修改全局变量,也不影响局部变量的值,局部变量被保护起来。每次执行是根据局部变量的变量值来进行运算