Python语言实践分析 -- 闭包
来源:互联网 发布:杭州淘宝摄影培训班 编辑:程序博客网 时间:2024/06/05 20:41
闭包定义
闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
示例
下面就是一个闭包的例子,可以看到inc3这个函数中引用到了外层传人的变量n,而这个n就是定义中的自由变量,在这里为3,而我们如果再定义一个inc2=inc(2),则在inc2中其自由变量为2。
def inc(n): def inner_func(x): return x+n return inner_funcinc3 = inc(3)assert inc3(2) == 5
_closure_
我们可以通过函数的 _closure_ 来查看其绑定的自由变量。
>>> inc3.__closure__(<cell at 0x0000000002E8F468: int object at 0x000000005FE3EFB0>,)
绑定的是变量而非对象
在Python中所有变量均是引用,而引用再绑定到实际的对象上,那么定义闭包时绑定的是自由变量,还是其指向的对象呢?我们设计如下代码在定义闭包函数后再更改自由变量,让其指向不同的对象,其执行结果显示为后面的对象,因此说明定义函数其绑定的是变量而非对象。
def out(n): def inner(): print(n) n = [] return innerout(1)()
其实这正是Python中迟绑定的机制,即闭包中变量的值只有在内部函数被调用时才会进行查询。
更改自由变量
某些情况下,我们想更改外部的自由变量,在Python2中是无法做到的,而在Python3中引入了nonlocal关键字,可以更改自由变量。
def out(n): def inner(): nonlocal n n += 1 print(n) return innerx = out(1)x(), x()# 结果# 2# 3
lambda
lambda也是同样的闭包原理,因此在使用lambda时也要注意闭包函数执行时才会查询实际值,否则可能出现意料外的情况。
def get_map_funs(n): return [lambda x:x**i for i in range(n)]print([j(2) for j in get_map_funs(6)])# 结果 [32, 32, 32, 32, 32, 32]
该问题有两种修改方式:
- 使用生成器:
def get_map_funs(n): return (lambda x:x**i for i in range(n))print([j(2) for j in get_map_funs(6)])#结果 [1, 2, 4, 8, 16, 32]
- i作为默认参数传入闭包函数中:
def get_map_funs(n): return [lambda x,i=i:x**i for i in range(n)]print([j(2) for j in get_map_funs(6)])#结果 [1, 2, 4, 8, 16, 32]
0 0
- Python语言实践分析 -- 闭包
- Python语言实践分析 -- 包导入
- Python语言实践分析 -- 默认参数
- Python语言实践分析 -- With语句
- R语言:spdep包(空间数据分析与R语言实践)
- R语言:spdep包(空间数据分析与R语言实践)
- Python语言学习笔记之闭包
- 闭包实践(一)------sicp图形语言--picture
- 语言实践(1)-任务分析
- 闭包的实践
- https实践之 抓包分析流程
- 空间数据分析与R语言实践
- python 性能分析与个人实践
- python数据分析实践(一)
- python数据分析实践(二)
- python数据分析实践(三)
- python数据分析实践(四)
- 拉格朗日插值法《python数据分析与挖掘实践》
- 第一天git学习记录
- oracle的字符集设置与乱码
- iOS基础
- WIN7与UBUNTU双系统的安装过程
- 专业术语
- Python语言实践分析 -- 闭包
- android 自定义View ----- 类似黄油相机添加文字
- css实现图片垂直水平居中
- LeetCode 260 Single Number III(只出现一次的数字 III)(*)
- mark关于Java语言Static的生命周期
- hibernate映射(四)——多对多
- 创建手机页面弹出键盘的时候背景图片被挤上去的解决办法
- eclipse导入项目出错
- 2015最流行的Android组件、工具、框架大全