python 闭包

1. 什么是闭包?

闭包应该说是一种写法,就是在函数嵌套的基础上,延伸了变量的作用域的写法。说起来可能有点绕,但是实际使用就不饶。

 

2. 我们考虑一下,为什么要用闭包,闭包到底是为了实现什么功能?

闭包其实是为了让函数本身保存当前的工作状态。就像类一样,类变量可以随着类里函数执行后,被改变:

比如:

class A:
  def __init__():
      self.cnt = 0

  def add(self):

      self.cnt = self.cnt+1

a = A()

a.add()

执行之后,我们就发现类变量self.cnt保存了运行的状态,也就是我们cnt+1可以被保存下来,并且不断叠加。

闭包的功能并不是必须的,因为完全可以用别的手段实现闭包。但是闭包的好处就在于,可以将保存状态本身这个工作,也放在函数里。

def func():
  cnt = []

  def add():

    cnt.append(1)

    return cnt

  return add

 

然后我们创建一个函数func的对象

a = func()   #会返回一个add函数对象

cnt = a() # [1]

cnt = a() # [1,1]

cnt = a() # [1,1,1]

但是cnt必须是可变的!!比如list这种,如果是不可变的,比如int,然后使用a = a+1在重新绑定的时候会出错!必须指明这个变量不是本地变量,而是访问的外部变量,用nonlocal关键字(和global类似)

def outer():
  a = 0
  def inner():
    nonlocal a
    a=a+1
    return a
  return inner

 

总的来说,如果要保存一个函数操作的历史记录,那么就可以使用闭包的写法,这样可以把一个变量一直存下来,供嵌套函数使用。如果不愿意写闭包,其实用类完全可以实现相同的功能。

 

我们再考虑另一种情况

a = 1
def func():
a = a+1
return a

这种也执行不会成功,因为a同样被认为是local变量,如何解决呢?与闭包类似,我们使用global(而不是nonlocal)来生命这个变量是全局变量

a = 1
def func():
global a
a = a+1
return a
这种情况其实和闭包是很类似的,都是变量作用域的延伸。

 

posted @ 2022-01-26 11:24  yjy888  阅读(59)  评论(0编辑  收藏  举报