文章目录

  • 1. 认识闭包
  • 2. 闭包简介
  • 3. 闭包作用
  • 4. 使用场景
  • 5. 总结


1. 认识闭包

在真正学习闭包之前,我们可以先看下面这段代码:

money = 1000
def buy(num):
    global money
    money -= num
    print("花费{},还剩{}".format(num, money))


buy(300)
buy(300)
buy(200)

用python编写微信群发红包 python发红包函数_用python编写微信群发红包


通过变量money记录总金额,函数buy来消费,把变量money设置成全局变量的方式来实现对变量money值的修改。虽然功能实现了,但是存在两个问题:

  • 代码不够整洁
  • 全局变量被修改

针对这两个存在的问题,我们可以通过闭包来实现:

def buy(money):
    def fun(num):
        nonlocal money
        money -= num
        print("花费{},还剩{}".format(num, money))
    return fun


fn = buy(1000)
fn(300)
fn(300)
fn(200)

用python编写微信群发红包 python发红包函数_用python编写微信群发红包_02

2. 闭包简介

维基百科定义:在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

简单来说,在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。

用python编写微信群发红包 python发红包函数_用python编写微信群发红包_03


注意:如果不修改外部函数的变量,只是引用,可以不用关键字nonlocal修饰变量

3. 闭包作用

通过上面的例子,我们可以看出闭包有如下作用:

  • 使用闭包不需要定义全局变量就可以实现通过函数,持续的访问,
  • 局部变量无法共享和长久的保存,而全局变量可能造成变量污染,闭包既可以长久的保存变量又不会造成全局污染。
  • 将外层函数的变量持久地保存在内存中,不会在外层函数调用后被自动清除。由于外层函数的变量在内存中被保存,因此会增加内存消耗,所以不能滥用闭包,否则会造成程序的性能问题,可能导致内存泄露。所以在退出函数之前,将不使用的局部变量全部删除。

4. 使用场景

闭包的作用我们都可以通过python中的来实现,那么闭包存在的意义在哪里呢?

  • 装饰器:python中的装饰器可以通过闭包来实现
  • 如果我们的对象中只有一个方法时,使用闭包比使用类更加简单和优雅(类似python中lambda匿名函数和方法)

5. 总结

  • 闭包函数: 定义双层嵌套函数, 内层函数可以访问外层函数的变量将内存函数作为外层函数的返回,此内层函数就是闭包函数
  • 闭包函数不定义全局变量,也可以让函数持续访问和修改一个外部变量
  • 闭包函数引用的外部变量,是外层函数的内部变量。作用域封闭难以被误操作修改
  • 使用闭包函数会占用额外的内存
  • 使用闭包函数,想要修改外部函数的变量值,需要用nonlocal关键字声明这个外部变量