1.闭包的理解

我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。

2. 闭包的格式

下面用伪代码进行闭包格式的描述

def 外层函数(参数):
def 内层函数():
print("内层函数执行", 参数) return 内层函数 内层函数的引用 = 外层函数("传入参数")
内层函数的引用()

外层函数中的参数,不一定要有,据情况而定,但是一般情况下都会有并在内函数中使用到

案例

def func(a, b):
def line(x):
return a * x - b return line line = func(2, 3)
print(line(5))

结果得到 7
在这个案例中,外函数func有接收参数 a=2,b=3,内函数line接收参数x=5,在内函数体中计算了a*x-b 即 2×5-3的值作为返回值,外函数返回内函数的引用,这里的引用指的是内函数line在内存中的起始地址,最终调用内函数line()得到返回值7

3.内函数中修改外函数的值

一般在函数结束时,会释放临时变量,但在闭包中,由于外函数的临时变量在内函数中用到,此时外函数会把临时变量与内函数绑定到一起,这样虽然外函数结束了,但调用内函数时依旧能够使用临时变量,即闭包外层的参数可以在内存中进行保留
如果想要在内函数中修改外函数的值,需要使用 nonlocal  关键字声明变量

def func(a, b):
def line(x):
nonlocal a
a = 3
return a * x - b return line line = func(2, 3)
print(line(5))

此时运行结果为:12

python面试题:

Python面试题:以下代码将输出什么?

def testFun():
temp = [lambda x : i*x for i in range(4)]
return temp
for everyLambda in testFun():
print (everyLambda(2))

脑中默默一想,这还用说么,肯定是:

0,2,4,6

然鹅正确答案:

6,6,6,6

原因:

Python 的闭包的后期绑定导致的 late binding,这意味着在闭包中的变量是在内部函数被调用的时候被查找。所以结果是,当任何 testFun() 返回的函数被调用,在那时,i 的值是在它被调用时的周围作用域中查找,到那时,无论哪个返回的函数被调用,for 循环都已经完成了,i ***的值是 3,因此,每个返回的函数 testFun 的值都是 3。因此一个等于 2 的值被传递进以上代码,它们将返回一个值 6 (比如: 3 x 2)

怎么解决呢??

1:创建一个闭包,通过使用默认参数立即绑定它的参数

def testFun():
temp = [lambda x ,i=i: i*x for i in range(4)]
return temp
for everyLambda in testFun():
print (everyLambda(2))

2:使用functools.partial 函数,把函数的某些参数(不管有没有默认值)给固定住(也就是相当于设置默认值)

from functools import partial
from operator import mul
def testFun():
return [partial(mul,i) for i in range(4)]
for everyLambda in testFun():
print (everyLambda(2))

3:优雅的写法,直接用生成器

def testFun():
return (lambda x ,i=i: i*x for i in range(4)) for everyLambda in testFun():
print (everyLambda(2))

4:利用yield的惰性求值的思想

def testFun():
for i in range(4):
yield lambda x : i*x
for everyLambda in testFun():
print (everyLambda(2))

最新文章

  1. REDHAT一总复习1 ssh配置 禁用root用户SSH连接
  2. Android闹钟 AlarmManager的使用
  3. Hadoop中JAVA不经过Catch(Exception e)直接到finally或者退出原因
  4. jmeter 构建一个Web测试计划
  5. DrawerLayout带有侧滑功能的布局类(2)
  6. 《架构探险——从零开始写Java Web框架》这书不错,能看懂的入门书
  7. Active MQ C#实现
  8. Swift - 故事板storyboard的用法
  9. 《WordPress插件开发手冊》文件夹
  10. Eclipse+Maven创建webapp项目<一> (转)
  11. 初学MySQL基础知识笔记--02
  12. [福州大学]W班平时成绩排名
  13. VsCode插件开发之入门示例
  14. mfc editline 变为大框框
  15. 【做题】Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆环
  16. ssm项目中遇到微信用户名称带有表情,插入失败问题
  17. mysql插入中文乱码
  18. Javascript 对象的创建和属性的判定
  19. mysql主主同步设置
  20. 在 Ubuntu13.10 服务器中安装 Munin(监视工具)【转】

热门文章

  1. PySpark DataFrame 添加自增 ID
  2. Linux Swap故障之 swapoff failed: Cannot allocate memory
  3. HTML那些标签已废弃,被代替
  4. 【使用DIV+CSS重写网站首页案例】CSS盒子模型
  5. C++学习(10)—— 对象模型和this指针
  6. Python3如何上传自己的PyPI项目
  7. Educational Codeforces Round 68 E. Count The Rectangles
  8. 项目Beta冲刺(团队)--6/7
  9. can总线学习网上资料汇总
  10. 论文画图工具使用(2)vision软件