函数闭包
闭包函数
在Python中,如果一个嵌套函数引用了其外层函数的局部变量,并且外层函数将这个内层函数返回,那么这个内层函数就被称为闭包函数,这个过程被称为闭包。
闭包函数的判定条件:
- 内函数使用了外函数的局部变量。
- 外函数返回内函数。
基本语法形式
def zhaoshenyang_family():
father = "马云"
def hobby():
print("我对钱没有一丝丝的兴趣,我不看重钱,这是我爸爸{}说的".format(father))
return hobby #返回函数引用
func = zhaoshenyang_family() #调用函数 返回内函数的引用
func() #使用闭包
# 使用 __closure__ 属性和 cell_contents 方法查看闭包中的自由变量
print(func.__closure__[0].cell_contents)
闭包的复杂形式
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()
lst = func()
# 获取哥哥函数
gege = lst[0]
gege()
# 获取弟弟函数
didi = lst[1]
didi()
# 使用 __closure__ 属性和 cell_contents 方法查看闭包中的自由变量
print(func.__closure__[0].cell_contents)
print(func.__closure__[1].cell_contents)
在这个例子中,gege_hobby和didi_hobby都是闭包函数,因为它们都引用了外层函数zhaowanli_family的局部变量money。zhaowanli_family函数返回了一个包含这两个闭包函数的列表,所以big_master也是一个闭包函数。
闭包的特点和意义
闭包的特点
在闭包函数中,内函数使用了外函数的局部变量,该变量会与内函数发生绑定,延长该变量的生命周期,持续到脚本执行结束。
def outer(val):
def inner(num):
return val + num
return inner
func = outer(10)
res = func(15)
print(res) # This will print 25
在这个例子中,inner函数引用了外函数outer的局部变量val,并且outer函数返回了inner函数,所以inner函数是一个闭包函数。尽管outer函数的调用已经结束,但是val的生命周期被延长了,它会一直存在,直到闭包函数inner不再被使用。
闭包的意义
全局变量的作用域大,容易被篡改。闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用,外部无法访问。
例如,我们有一个全局变量num,在一个函数中我们需要频繁地修改这个变量的值。但是,全局变量很容易被其他函数或者代码篡改,这可能会导致我们的函数行为出现错误。
num = 0
def click_num():
global num
num += 1
print(num)
click_num()
click_num()
click_num()
num = 100 # The global variable num is changed by other code
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 # This will not affect the x in the closure
click_num()
click_num()
在这个例子中,我们使用闭包替代了全局变量,使得x的值只能通过click_num函数来修改,其他的代码无法访问或者修改这个值。这样可以保护我们的变量不被意外修改,使得代码更加安全。

浙公网安备 33010602011771号