什么是闭包?

什么是闭包?

不知道大家有没看见过这样的代码。

def fun1():
 ........


突然在某个地方,看到 return fun1 又看到 return fun1(), 是不是彻底懵了,这两个到底是什么啊,有什么区别吗?
若你学过C++中的仿函数和bin函数,你大概就知道这是什么意思了。下面我们做几个简单的例子学习下,什么是闭包。

首先理解什么是内嵌函数?

顾名思义就是函数内,再申明函数,来举个例子
    def fun1():
        ...
        ...
        def fun2():...
        ...
        ...

这种类似的代码见过吧,这里面def fun2():... 指的是在 fun1中 内嵌函数fun2 , "..."的意思是稍后实现。
我们来写一个 5*y 的函数吧。

def fun1():
    x = 5
    def fun2(y):
        return x*y
    
    return fun2

这里我们看到的开始我们说的 return fun2了。这是啥意思啊。意思就是:
1、我们调用fun1()时,返回的是一个fun2函数
这个返回有什么特点吗?
2、 返回的fun2(),包含有fun1()的局部变量,我们知道一个函数是不能被外部访问的。而使用closure就可以附带上下文。

下面我们来看怎么调用。

#第一种方法
y = 10
f_2 = fun1()
type(f_2)

result = f_2(y)
print(result)
50

我们看到fun1()调用后,我们用type(f_2)的结果是function,没错return fun2 返回的就是一个函数,
我们接下就可以使用f_2(y)来得到我们要的结果50啦。
这是不是有点像我们面向对象编程时:
类 类对象名
类对象名(参数)
这里举例不恰当,大概明白什么意思就好了。

#第二种方法
result_2 = fun1()(9)
print(result_2)
45
  • 哇晒!这种是不是像仿函数的调用。当然不了解仿函数也没关系。
    我们来理解一下 fun1()(9)
    1、首先fun1()是不是就是相当于上个例子中的f_2,
    2、fun1()(y) = f_2(y)
    3、 f_2(y) 返回的是什么啊,就是return x*y

那我们看看什么情况是 return fun2()这种类型的呢?

def fun3(x):
    y = 5
    def fun4():
        return x*y
    return fun4()
f_3 = fun3(5)
type(f_3)

'''
int
'''
'\nint\n'

return fun4() 是什么意思啊,就是调用fun4(), 返回fun4执行的返回值

print(f_3)
25
### 我们来看常见的使用return fun4()之类的错误吧。

直接调用fun5()会出现什么错误呢


UnboundLocalError: local variable 'x' referenced before assignment

哇晒! 这个错误是不是经常看到啊。 因为x *= x ,而x是局部变量

那么应该怎么解决呢?

# 第一种容器,我们来修改代码
def fun5():
    x = [6]
    def fun6():
        x[0] *= x[0]
        return x[0]
    
    return fun6()
fun5()
36

结果是不是我们想要的呢。我们来看第二种解决方法,nonlocal关键字,这个关键字,就是告诉它,x不是局部变量

def fun5():
    x = 8
    def fun6():
        nonlocal x
        x *= x
        return x
    
    return fun6()
fun5()
64

posted @ 2020-05-13 15:17  cyssmile  阅读(243)  评论(0编辑  收藏  举报