先上代码:

1 def listFuc():
2     temp = [lambda x: i*x for i in range(4)]
3     return temp
4 for singleFuc in listFuc():
5     print (singleFuc(2))

上面这段代码输出结果是什么呢?

我们可能会想:listFuc这个函数是将temp这个list返回,而temp里面的元素是匿名函数,匿名函数传入参数为x,返回值为 i*x, i依次为0,1,2,3. 所以在下面这个for循环里面,将2依次传入这4个匿名函数里对x赋值,print输出返回的结果,所以结果是 0*x,1*x,2*x,3*x,即 0 2 4 6

但结果确是:

6
6
6
6

为什么呢?

原因在于Python的迟绑定(late binding)机制。

闭包中内部函数的值只有在被调用时才会进行查询。

首先此匿名函数传入参数只有x,虽然返回的是i*x,但是现在传入参数中并没有i,没有对匿名函数内部的i赋值,所以相当于你申明了返回了4个函数:

lambda x: i*x
lambda x: i*x
lambda x: i*x
lambda x: i*x

for i in range(4)这句代码起到的作用仅仅是循环4次得到4个如上面那样的匿名函数。

因此等到listFuc函数返回的lambda函数被调用时,会在附近的作用域中查询变量i的值,而在listFuc生成返回数组之后,i的值是3,因此singleFuc实际上都是:

lambda x: 3*x

所以最后输出的结果就是 6666 了

666666

那么要输出 0 2 4 6时,解决办法是在定义匿名函数时,就将i的值作为参数传入匿名函数内部:

1 def listFuc():
2     temp = [lambda x,i=i: i*x for i in range(4)]
3     return temp
4 for singleFuc in listFuc():
5     print (singleFuc(2))

这样,在每次创建匿名函数时,实际上是这样的过程:

lambda x,i=0: i*xlambda x,i=1: i*xlambda x,i=2: i*xlambda x,i=3: i*x

所以singleFuc每次传入参数2作为x的值时,i都已经被赋了值。

for i in range(4)这句代码的作用就不仅是循环4次得到4个匿名函数了,还充当了对匿名函数内部作用域变量赋值的作用
这样写可能会更好理解:
1 def listFuc():
2     temp = [lambda x,y=i: y*x for i in range(4)]
3     return temp
4 for singleFuc in listFuc():
5     print (singleFuc(2))

结果就是:

0
2
4
6

参考:http://www.cnblogs.com/harelion/p/5577087.html

转载于:https://www.cnblogs.com/Anythingkk/p/9000871.html

Python 闭包相关之late binding机制相关推荐

  1. python生产实战 python 闭包之庖丁解牛篇

    python生产实战 python 闭包之庖丁解牛篇 python生产实战 从闭包到中间件 什么是闭包 计算机中的闭包 数学领域中的闭包 闭包使用场景 C/C++ 中的闭包思想 C 中类似闭包的结构 ...

  2. 深入理解Python闭包概念

    闭包并不只是一个Python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...

  3. Python的try... excep异常捕捉机制

    Python的try... excep异常捕捉机制 一.没有加入异常捕捉机制 二.加入try ... except 异常捕捉 1.已知错误类型 (例如下面已知列表索引错误类型`IndexError`) ...

  4. Python闭包及其作用域

    Python闭包及其作用域 关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记 如果在一个内部函数里,对一个外部作用域(但不是全局作用域 ...

  5. Python 闭包详解

    在函数编程中经常用到闭包.闭包是什么,它是怎么产生的及用来解决什么问题呢.给出字面的定义先:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个 ...

  6. Python内存相关

    Python内存相关 示例一: v1 = [1, 2, 3] v2 = [1, 2 ,3]v1 = 123 v2 = 123v1 = "dogfa" v2 = "dogf ...

  7. python闭包的应用场景_简单谈谈Python中的闭包

    Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚.我在脚本之家搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容. 1. 闭包的概念 首 ...

  8. python闭包的应用场景_Python闭包函数定义与用法分析

    python函数的闭包怎么理解小编憎恨离别.但若,离别能让你牵挂,小编愿意离开你. 1. 闭包的概念 首先还得从基本概念说起,什么是闭包呢?来看下维基上的解释: 复制代码代码如下: 在计算机科学中,闭 ...

  9. [转载] 根据Python常见面试题来谈谈 Python 闭包

    参考链接: Python闭包 这里根据我们平常见到的一些Python常见面试题来跟大家说一下关于Python闭包的相关问题! 题目: 1.什么是闭包?闭包的定义? 2.手写一个简单的闭包 3.变量作用 ...

最新文章

  1. 平凡的世界,有感而发
  2. Epox 8RDA3G主板奇怪的问题
  3. vscode创建工作区_区民政局党员干部下沉社区,积极参与文明创建工作
  4. 把一个人的特点写具体作文_把一个人的特点写具体作文
  5. 总结一下在ASP.NET中开发网站的一般步骤
  6. 远程体验Linux Lite
  7. java ut_【JAVA UT】2、写UT的科学步骤
  8. 递归方式计算一个数的几次方
  9. java 枚举 中文_JAVA枚举类的简单使用
  10. 【Tableau server 8.0】Tableau server 考试真题回顾总结
  11. app软件怎么申请软件著作权?
  12. clickhouse 集群异常排查处理总结
  13. 后台模板vue-admin-template的安装
  14. 计算机系英文简历常用的词汇,计算机专业英文简历词汇
  15. bread是可数还是不可数_学了20年英语才明白:bread为什么是不可数名词?
  16. 项目实战!用爬虫和Flask打造属于自己的电影网站
  17. Change to survive
  18. 十年再出发,Dubbo 3.0 Preview 即将在 3 月发布
  19. ad服务器做虚拟化,VMware ESXi 4.1新特性之AD服务器集成
  20. crs-2632 crs-2674

热门文章

  1. 磁盘被占满   系统出现 no space left on 报错(block被占满/inode被占满)
  2. Android Scroller简单用法
  3. 浙江大学PAT考试1009~1012(1010上帝是冠军。。)
  4. 心累了,就笑一笑,学会爱自己
  5. [导入]圣诞快乐,快乐圣诞。。。。。。
  6. 第二十到第二十一天:让你和页面对话-IFE
  7. 一天一点linux(9):ubuntu下如何搭建LAMP开发环境?
  8. 转;说说AngularJS中的$parse和$eval
  9. Android 百度地图 SDK v3.0.0 (二) 定位与结合方向传感器
  10. F#中的异步和并行设计模式(三):代理