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))

闭包(python)的更多相关文章

  1. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  2. python教程与资料

    网上有个人写的python快速教程,非常好.比看书好多了.猛击下面的链接地址 http://www.douban.com/group/topic/30008503/ python文档资料收集 pyth ...

  3. 【Python大系】Python快速教程

    感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容很多,加上各种标准库.拓展库, ...

  4. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  5. Python快速教程目录(转)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容 ...

  6. Python快速教程

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容 ...

  7. python基础教程

    转自:http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html Python快速教程 作者:Vamei 出处:http://www.cn ...

  8. Python系列教程大汇总

    Python初级教程 Python快速教程 (手册) Python基础01 Hello World! Python基础02 基本数据类型 Python基础03 序列 Python基础04 运算 Pyt ...

  9. Python入门学习(一)

    看完了莫烦Python的视频,对于Python有了一点感觉,接下来打算把小甲鱼的视频啃完,附上学习网址:http://blog.fishc.com/category/python 小甲鱼的视频是从零基 ...

  10. Python全栈之路----目录

    Module1 Python基本语法 Python全栈之路----编程基本情况介绍 Python全栈之路----常用数据类型--集合 Module2 数据类型.字符编码.文件操作 Python全栈之路 ...

随机推荐

  1. ajax加载验证码这样不断刷新的文件无法刷新问题

    看了很多网站,在前端不设置缓存,这样会把需要缓存的数据漏掉 觉得欺骗浏览器的方式很不错,方式如下 为了在所有浏览器上都能实现点击验证码的刷新功能,我们可以在上述代码中添加随机参数,对浏览器进行欺骗. ...

  2. pyechart基本使用大全

    charts_base 原文链接:https://blog.csdn.net/weixin_43735353/article/details/89328048 图表详细配置请参考 图表配置篇 基本图表 ...

  3. jperf windows

    jperf windows版是款简单实用的网络性能测试的工具:它也是款图形界面的iperf程序,可以这进行使用JPerf程序的时候,快速的进行简化您的命令行参数,而且这进行测试结束之后,还是以图形化的 ...

  4. scratch2.0的教材视频,王木头系列

    在线视频 http://v.qq.com/vplus/d05a62f676f6f3b6b87401b4530cff9a?page=cover 理论辩证 https://www.sohu.com/a/1 ...

  5. MongoDB安装启动教程

    MongoDB安装启动教程 简易教程:鉴于第一次大家使用分布式数据库,提供一个简易教程(也可看老师的PPT或者视频) 1.点击安装包(老师给的),安装目录不要更改,否则后面配置需要改,可能导致装不上 ...

  6. Dump文件的生成和使用

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lk142500/article/detai ...

  7. P5022 旅行[基环树]

    以后必须学会面向数据编程!看半天题目不知道咋写直接爆搜,结果分少的可怜,还不如直接贪搞个60分. 观察数据,发现图至多存在一个环. 显然,如果没有环,这个题不跟你多bb,直接贪就完事了,线性复杂度. ...

  8. Jenkins的HTML报告增加显示Throughput展示

    第一步,在summary中添加 在pagelist中添加 关于display-QPS部分,参考我的博文的另外一篇. 生成的报告如下:

  9. libimobiledevice的安装与使用

    说明:libimobiledevice相当于安卓的adb,可以使用命令对ios应用进行安装卸载等操作. 在MacOS下安装libimobiledevice: $ brew uninstall idev ...

  10. Ofbiz项目学习——阶段性小结——服务返回结果

    一.返回成功 1.在.DispatcherReturnDemoService类中编写服务[returnSuccess],内容如下: /** * 返回成功结果 * @param dctx * @para ...