Python中的闭包与参数引用域
我的机器学习教程「美团」算法工程师带你入门机器学习 以及 「三分钟系列」数据结构与算法 已经开始更新了,欢迎大家订阅~这篇专栏整合了这几年的算法知识,简单易懂,也将是我实体书的BLOG版。
欢迎大家扫码关注微信公众号「图灵的猫」,除了有更多AI、算法、Python相关文章分享,还有免费的SSR节点和外网学习资料。其他平台(微信/知乎/B站)也是同名「图灵的猫」,不要迷路哦~
今天在慕课网刷廖老师的Python进阶课程,有道题很有意思,题目是这样的:
在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问:
def g():print 'g()...'def f():print 'f()...'return g
将 g 的定义移入函数 f 内部,防止其他代码调用 g:
def f():print 'f()...'def g():print 'g()...'return g
但是,考察上一小节定义的 calc_sum 函数:
def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum
注意: 发现没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 lst。
像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:
# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():fs = []for i in range(1, 4):def f():return i*ifs.append(f)return fsf1, f2, f3 = count()
def count():fs = []for i in range(1, 4):def f():return i*ifs.append(f)return fsf1, f2, f3 = count()
你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果全部都是 9(请自己动手验证)。
原因就是当count()函数返回了3个函数时,这3个函数所引用的变量 i 的值已经变成了3。由于f1、f2、f3并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:
>>> f1()
9 # 因为f1现在才计算i*i,但现在i的值已经变为3
# 因为f1现在才计算i*i,但现在i的值已经变为3
因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。
然后有位评论给出的见解我觉得非常厉害,他说,问题的产生是因为函数只在执行时才去获取外层参数i,若函数定义时可以获取到i,问题便可解决。而默认参数正好可以完成定义时获取i值且运行函数时无需参数输入的功能,所以在函数f()定义中改为f(m = i),函数f返回值改为m*m即可。
因此,改写后的函数应该为
def count():
fs = []
for i in range(1, 4):
def new(j = i):
return j * j
fs.append(new)
return fs
f1, f2, f3 = count()
print f1(), f2(), f3()
Python中的闭包与参数引用域相关推荐
- Python 中的闭包、匿名函数、decorator 装饰器与python的偏函数
Python中的闭包 def calc_sum(lst):def lazy_sum():return sum(lst)return lazy_sum 像这种内层函数引用了外层函数的变量(参数也算变量) ...
- python闭包的应用场景_简单谈谈Python中的闭包
Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚.我在脚本之家搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容. 1. 闭包的概念 首 ...
- Python中的闭包
(如转载,请注明出处,谢谢.) 闭包这个概念在很多语言中都有涉及,本文主要谈谈python中的闭包.Python中使用闭包主要是在进行函数式开发时使用. 一,定义 python中的闭包从表现形式上定义 ...
- Python 中的闭包介绍
引言 闭包是优雅的 Python 结构.在本文中,我们将了解它们,如何定义闭包,为什么以及何时使用它们. 但是在讨论什么是闭包之前,我们必须首先理解什么是嵌套函数,以及作用域规则是如何为它们工作的.那 ...
- 什么是闭包及Python中的闭包
什么是闭包 Objects are data with methods attached. Closures are functions with data attached. 一般来说,我们都非常熟 ...
- python中的闭包(closure)
背景 本文尝试介绍Python中的闭包(closure),包括闭包是什么? 为什么要使用闭包?如何使用闭包? 嵌套函数及非局部变量 在介绍闭包之前,需要先明白什么是嵌套函数和非局部变量.在一个函数(f ...
- python中什么是可变参数_详解Python的三种可变参数
详解Python的三种可变参数 可变参数 可变参数应该最简单,在C/C++和Java等语言中都有,就是用*号来表示,例如 def testArg(*arg) 你可以传入任意多个元素(包括0)到参数中, ...
- python闭包与装饰器有啥关系_深入理解Python中的闭包与装饰器
函数的装饰器可以以某种方式增强函数的功能,如在 Flask 中可使用 @app.route('/') 为视图函数添加路由,是一种十分强大的功能.在表现形式上,函数装饰器为一种嵌套函数,这其中会涉及到闭 ...
- Python中的闭包总结
前几天又有人在我的这篇文章 python项目练习一:即时标记 下留言,关于其中一个闭包和re.sub的使用不太清楚.我在自己的博客上搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善博客上P ...
- python闭包和装饰器的区别_深入理解Python中的闭包与装饰器
函数的装饰器可以以某种方式增强函数的功能,如在 Flask 中可使用 @app.route('/') 为视图函数添加路由,是一种十分强大的功能.在表现形式上,函数装饰器为一种嵌套函数,这其中会涉及到闭 ...
最新文章
- C#+Mapxtreme 实现一些GIS系统基本的功能
- redis批量操作及性能分析
- 使用R画桑基图(流程图)
- sobel算子_OpenCV 学习:4 Sobel算子
- WPF 用代码实现WrapPanel右侧自动对齐(解决多余空白问题)
- Android 中流量、电量、弱网环境怎么测?
- 通过wifi使用nfs把ubuntu挂载到android
- httpClient4 设置代理
- ES索引重建reindex详解
- Python:存取npy格式数据
- TRACE32——List源代码查看
- darknet源码解析:networ结构体之input_pinned_gpu
- CCW:浪潮云+智能协同云平台获评“用户首选品牌”
- MacBook Pro做为Windows电脑的扩展屏【已解决】
- 不一样的课程表,不一样的Excle--用Excle进行设计(42):排序所演绎的数据逻辑
- Java学习之路-开局
- 乐优商城:笔记(六):上传微服务:LyUpload
- 网站常用的favicon.ico文件
- 最新电脑CPU天梯图
- jenkins自动化_通过Jenkins自动化PSR合规性