闭包
通过学习可知函数可以通过return返回一个变量,此外,也可以返回一个函数名,如下所示。
1 def f1():
2 print('f1()函数')
3 def f2():
4 print('f2()函数')
5 return f1
6 x = f2()
7 x()
8 f1() # 正确
运行结果如下图所示。
运行结果
在上例中,第5行在函数f2()中返回一个函数名f1,第6行调用f2()函数并将返回值赋值给x,第7行通过变量x间接调用f1()函数。
此外,还可以将f1()函数的定义移动到f2()中,这样f2()函数外的作用域就不能直接调用f1()函数,如下所示。
1 def f2():
2 print('f2()函数')
3 def f1():
4 print('f1()函数')
5 return f1
6 x = f2()
7 x()
8 # f1() 错误
运行结果如下图所示。
运行结果
运行结果在上例中,函数f1()的定义嵌套在函数f2()中,此时在函数f2()外的作用域不能直接调用函数f1(),如第8行代码。
将一个函数的定义嵌套到另一个函数中,还有其他的作用,如下所示。
1 list1 = [1, 2, 3, 4, 5]
2 def f2(list):
3 def f1():
4 return sum(list)
5 return f1
6 x = f2(list1)
7 print(x())
运行结果如下图所示。
运行结果
在上例中,函数f2()中传入一个参数,在函数f1()中对该参数中的元素求和,具体执行过程如下图所示。
执行过程.png
在上图中,list1作为参数传进函数f2()中,此时不能把函数f1()移到函数f2()的外面,因为函数f1()的功能是计算list中所有元素值的和,所以f1()函数必须依赖于函数f2()的参数,如果函数f1()在函数f2()外,则无法取得f2()中的数据进行计算,这就引出了闭包的概念。
如果内层函数引用了外层函数的变量(包括其参数),并且外层函数返回内层函数名,此时就称内层函数为闭包。从概念中可以得出,闭包需要满足的三个条件:
- 内层函数的定义嵌套在外层函数中
- 内层函数引用外层函数的变量
- 外层函数返回内层函数名
网友评论