加载中...

函数闭包

闭包函数

在Python中,如果一个嵌套函数引用了其外层函数的局部变量,并且外层函数将这个内层函数返回,那么这个内层函数就被称为闭包函数,这个过程被称为闭包。

闭包函数的判定条件:

  1. 内函数使用了外函数的局部变量。
  2. 外函数返回内函数。

基本语法形式

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_hobbydidi_hobby都是闭包函数,因为它们都引用了外层函数zhaowanli_family的局部变量moneyzhaowanli_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函数来修改,其他的代码无法访问或者修改这个值。这样可以保护我们的变量不被意外修改,使得代码更加安全。

posted @ 2024-03-02 16:05  江寒雨  阅读(44)  评论(0)    收藏  举报