浅谈Python闭包
闭包是在其词法上下文中引用了自由变量的函数。
通俗地说,就是函数嵌套(后续称之为外层函数)另外一个函数(后续称之为内层函数),在内层函数中,引用外层函数的变量,每次对内层函数的调用,外层函数变量的值都会进行保持。
用个简单的例子来说明,使用闭包实现一个函数,求所有传入的数字的平均值。
def averager():
"""
闭包实现求平均值的例子
每次传入一个数字,返回所有传入的数字的平均值
:return:
"""
count = 0
total = 0.0 def _averager(value):
nonlocal total, count
total += value
count += 1
average = total/count
return average return _averager # 调用外层函数averager,得到内层函数_averager的对象,赋值给avg
# 此时闭包形成,外层函数的变量total, count, average会被保持
avg = averager()
# 每次调用内层函数avg时,外层函数变量的值都会被记住
# 第一次调用,外层函数的变量count=1, total=10.0, average=10.0
print(avg(10))
# 10.0
# 第二次调用,外层函数变量的值不会重置,仍然保持上次调用的结果
# 此时 count=2, total=30.0, average=15.0
print(avg(20))
# 15.0
# 第三次调用,外层函数变量的值仍然会保持上次调用的结果
# 此时 count=3, total=36.0, average=12.0
print(avg(6))
# 12.0
上面的例子中,最重要的部分在调用外层函数averager时,需要返回内层函数的对象_averager,注意这里的return _averager没有括号,并不是调用内层函数,而是返回内层函数的对象。
avg_cls = Averager()当调用外层函数,返回内层函数对象时,即形成闭包。
avg(10)每次对内层函数的调用,外层函数中的变量的值,都会被记住,即保持上次调用的结果。
如果不容易理解,可以用类实例实现类似上面闭包的功能,实际执行中,因为类实例self的参与,运行速度要略慢于闭包的实现。
# 以类实现类似上面闭包的功能
class Averager: def __init__(self):
self.count = 0
self.total = 0.0 def __call__(self, value):
self.total += value
self.count += 1
average = self.total/self.count
return average avg_cls = Averager() print(avg_cls(10))
# 10.0
print(avg_cls(20))
# 15.0
print(avg_cls(6))
# 12.0
上面这个使用类实现的例子中,变量count和total,都保存在类实例avg_cls中,每次对类实例的调用,都会调用__call__方法计算平均值,因为是同一个实例,所以count和total的值都会存储在实例中。
闭包也是类似的效果,变量count和total也是存储在外层函数的上下文中,所以每次对内层函数调用,外层函数的变量不会被销毁,而是一直保持初始值(未调用内层函数时)或上次调用的结果(每次调用内层函数后,对count和total的修改都会被存储)。
浅谈Python闭包的更多相关文章
- 浅谈python闭包及装饰器
1. 什么是闭包: 闭包 是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变 ...
- 开发技术--浅谈Python函数
开发|浅谈Python函数 函数在实际使用中有很多不一样的小九九,我将从最基础的函数内容,延伸出函数的高级用法.此文非科普片~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...
- 浅谈Python时间模块
浅谈Python时间模块 今天简单总结了一下Python处理时间和日期方面的模块,主要就是datetime.time.calendar三个模块的使用.希望这篇文章对于学习Python的朋友们有所帮助 ...
- 浅谈Python在信息学竞赛中的运用及Python的基本用法
浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...
- 浅谈python字符串存储形式
http://blog.csdn.net/zhonghuan1992 钟桓 2014年8月31日 浅谈python字符串存储形式 记录一下自己今的天发现疑问而且给出自己现有知识有的回答. 长话短说,用 ...
- 开发技术--浅谈python数据类型
开发|浅谈python数据类型 在回顾Python基础的时候,遇到最大的问题就是内容很多,而我的目的是回顾自己之前学习的内容,进行相应的总结,所以我就不玩基础了,很多在我实际生活中使用的东西,我会在文 ...
- 开发技术--浅谈python基础知识
开发|浅谈python基础知识 最近复习一些基础内容,故将Python的基础进行了总结.注意:这篇文章只列出来我觉得重点,并且需要记忆的知识. 前言 目前所有的文章思想格式都是:知识+情感. 知识:对 ...
- [转]浅谈Python web框架
说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...
- 浅谈Python Web的五大框架
说到Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界.各种micro-framework.framework不可胜数. 尽管还有一大脚本语言PHP也有 ...
随机推荐
- Struts2中的图片验证码
1.Struts中建一个action <action name="Code" class="LoginAction" method="code& ...
- JAVA链表中迭代器的实现
注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...
- IT行业的创新的读后感
一.什么是创新 创新是以新思维.新发明和新描述为特征的一种概念化过程.它原意有三层含义,第一,更新:第二,创造新的东西:第三,改变.创新是人类特有的认识能力和实践能力,是人类主观能动性的高级表现形式, ...
- PAT L3-003 社交集群
https://pintia.cn/problem-sets/994805046380707840/problems/994805053141925888 当你在社交网络平台注册时,一般总是被要求填写 ...
- 为什么要用Thrift
Why Thrift, Why not HTTP RPC(JSON+gzip) https://stackoverflow.com/questions/9732381/why-thrift-why-n ...
- Vue.directive注册指令
指令定义函数提供了几个钩子函数(可选): vue指令的生命周期 bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作. inserted: 被绑定 ...
- 2016_NENU_CS_3
贴一下比赛的代码, 其中 I 题代码源于final大神 ok_again http://acm.hust.edu.cn/vjudge/contest/127444#overview I /***** ...
- ultraEdit MAC 破解方法
安装了个UltraEdit 但是需要验证码,太麻烦了,破解方法: 拷贝附件(command +c )然后在MAC的底下点击访达==>应用程序==>UltraEdit==>右击 显示包 ...
- codeforces515B
Drazil and His Happy Friends CodeForces - 515B Drazil有很多朋友,他们中有些人是快乐的,有些人是不快乐的. Drazil想让他的朋友变得快乐.于是, ...
- C# 对象与JSON字符串互相转换的三种方式
C# 对象与JSON字符串互相转换的三种方式 JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式. 关于内存对象和JSON字符串的相互转换, ...