浅谈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也有 ...
随机推荐
- Week 7 迭代总结
写在前面: 本次我为团队博客写了一篇总结,深刻总结了我们组发生的问题以及将来要做的事情.有兴趣请移步http://www.cnblogs.com/Buaa-software Week 7 Alpha轮 ...
- "Linux内核分析"第七周
可执行程序的装载 张文俊+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.预 ...
- R和python语言如何求平均值,中位数和众数
均值是通过取数值的总和并除以数据序列中的值的数量来计算. R语言平均值公式: mean(x, trim = 0, na.rm = FALSE, ...)#x - 是输入向量.trim - 用于从排序的 ...
- Spring基础之 反射(Reflection)
1.了解Class package com.inspire.reflection.Class_api; import java.lang.reflect.Constructor; import jav ...
- Oracle 的ORION工具简单使用
1. 下载地址: http://www.oracle.com/technetwork/cn/topics/index-088165-zhs.html 2. linux x64 还有 windows的 ...
- ubuntu安装命令
sudo apt-get update 更新源sudo apt-get install package 安装包sudo apt-get remove package 删除包sudo apt-cach ...
- Personal Software Process (PSP)
日期 分类 开始时间 结束时间 中断时间 净时间 活动 备注 C U 2016/03/15 随笔 9:30 10:40 0 70 博客更新 更新<软件项目管理(1)> Y Minute 随 ...
- 机器学习中的降维算法:ISOMAP & MDS
参见:https://blog.csdn.net/Dark_Scope/article/details/53229427
- java.util.concuttent Callable Future详解
在传统的多线程实现方式中(继承Thread和实现Runnable)无法直接获取线程执行的返回结果,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 从 ...
- codeforces625C
K-special Tables CodeForces - 625C 人们经常做一些疯狂的事来凸显自己.有的人跳舞,有的人撩妹,有的人立志成为顶级程序猿(例如某peng),还有的人喜欢收集有趣的数学对 ...