什么是闭包?
什么是闭包?
不知道大家有没看见过这样的代码。
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