python 闭包 closure 总结
来源:互联网 发布:米思米选型软件 编辑:程序博客网 时间:2024/06/10 21:25
本文总结自PROGRAMIZ的这里
1.内嵌函数的非本地变量
在另一个函数里面定义的函数,被称为内嵌函数。内嵌函数可以访问闭合范围内(就是外部函数范围)的变量,这些变量被称为非本地变量(nonlocal variable)。默认情况下,非本地变量是只读的。为了可以修改非本地变量,需要将它们生命为nonlocal,如下例所示。
def print_msg(msg):"""This is the outer enclosing function"""def printer():"""This is the nested function"""print(msg)printer()# We execute the function# Output: Helloprint_msg("Hello")可以看到,内嵌函数是printer(),可以访问非本地变量msg,msg定义在外部函数print_msg()里面。
2.定义一个闭包函数
在上面的例子中,如果print_msg()返回print()函数,而不是调用它,会发生什么?这要求函数被这样定义def print_msg(msg):"""This is the outer enclosing function"""def printer():"""This is the nested function"""print(msg)return printer # this got changed# Now let's try calling this function.# Output: Helloanother = print_msg("Hello")another()
这非同寻常。
print_msg()函数被通过传入“Hello”所调用,返回的函数被绑定为another. 在调用another()的时候,我们对print_msg()函数已经完成调用了,但是“Hello”仍然被记住了!
这种将一些数据("Hello")附加到代码的技术,被称为python里面的closure.
闭合范围内的数据(非本地变量)能够一直被记住,即便它们已经脱离了闭合范围或者外部函数已经被从命名空间删除.
在python shell里面继续运行下面的代码,看看会发生什么.
>>> del print_msg>>> another()Hello>>> print_msg("Hello")Traceback (most recent call last):...NameError: name 'print_msg' is not defined
3.怎样得到一个闭包函数?
从上面的例子可以看出,当我们让内嵌函数引用一个非本地变量,就得到了一个python closure.python closure必须满足以下三点标准:
1)必须有一个内嵌函数(函数里定义的函数)
2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量
3)外部函数必须返回内嵌函数
4.什么时候使用closure?
closure适合做什么?closure可以减少使用全局变量和提供一定程度的数据隐藏.
当一个类只有很少的方法(通常是一个),closure可以提供一种更优雅的替代方案。但如果类的属性或者方法开始增多,最好还是实现一个类。
下面是一个closure也许比类更好的一个例子。当然,到底哪个更好最终还是取决与你。
def make_multiplier_of(n): def multiplier(x): return x * n return multiplier# Multiplier of 3times3 = make_multiplier_of(3)# Multiplier of 5times5 = make_multiplier_of(5)# Output: 27print(times3(9))# Output: 15print(times5(3))# Output: 30print(times5(times3(2)))
python的装饰器可以扩展closure的功能,详情戳这里.
5.获取闭合数值
最后还有一个友情提示,所有在外部函数定义的非本地变量,都可以被获取到。所有的函数对象都有一个__closure__属性,如果它是一个闭包函数,那么它包含一个cell objects元组。
就上面的例子,我们知道time3和times5是闭包函数
>>> make_multiplier_of.__closure__>>> times3.__closure__(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)
cell object有cell_contents属性,保存了闭合数值>>> times3.__closure__[0].cell_contents3>>> times5.__closure__[0].cell_contents5
扫面下方二维码,见证奇迹的发生
0 0
- python 闭包 closure 总结
- Python闭包Closure
- Python Closure 闭包
- Python 闭包 ( closure )
- Python中的闭包-closure
- Python 中的闭包 —— Closure
- Swift 闭包(Closure)总结
- 闭包Closure
- Javascript闭包(Closure)
- Javascript--闭包(closure)
- Javascript闭包(Closure)
- 闭包closure
- Javascript闭包(Closure)
- 什么是闭包(Closure)?
- javascript closure 闭包
- Javascript闭包(Closure)
- 闭包(closure)
- swift closure 闭包
- Tomcat启动时自动加载Servlet
- 快速排序
- CentOS安装Nginx
- implements
- CentOS安装Redis
- python 闭包 closure 总结
- 选择排序
- Spring-beans-4.3.2.jar包目录结构
- 判断文件是否为gif/jepg/png等格式
- 使用 AF_UNIX 实现本机数据流通信
- Hibernate相关知识点总结
- Cascade和inverse的区别
- Android Studio初学(一)----加快运行速度
- 50x50矩阵内画等腰直角三角形,并统计三角形内元素之和