浅谈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也有 ...
随机推荐
- warning C4996: 'strcpy': This function or variable may be unsafe.
mkdir 写成 _mkdir strcpy 写成为 strcpy_s 或是在项目处右击-->属性-->C/C++-->预处理器-->在预处理器定义后添加";_CR ...
- python 函数及变量作用域及装饰器decorator @详解
一.函数及变量的作用 在python程序中,函数都会创建一个新的作用域,又称为命名空间,当函数遇到变量时,Python就会到该函数的命名空间来寻找变量,因为Python一切都是对象,而在命名空间中 ...
- JVM EXCEPTION_ACCESS_VIOLATION
## A fatal error has been detected by the Java Runtime Environment:## EXCEPTION_ACCESS_VIOLATION (0x ...
- 属性动画总结(Property Animation)
一.概述 属性动画可以作用在View的属性上,对属性进行修改,而且不要求对应的属性一定是有显示效果的. 二.属性动画的实现方式 1.基础的类Animator Animator是一个抽象类,是属性动画的 ...
- QQ互联登录提示redirect uri is illegal(100010)完美解决方法
大概2015年3月低,腾讯QQ互联开发平台调整了有关QQ登录应用回调地址填写规则,用来修复QQ登录过程因回调地址的漏洞可能导致存在的安全问题. 博主接触这块较多,但也是四月才了解此事,从4月起,所有新 ...
- ionic动态切换主题皮肤
本来想通过css自定义属性值: :root{ --red:red; } p{ color:var(--red); } div{ background:var(--red); } 在ionic2设置动态 ...
- delphi获取一个窗口的所有子窗口(包括嵌套)
unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...
- AXI4
axis AXI4-stream 去掉了地址项,允许无限制的数据突发传输规模: 摘自http://xilinx.eetrend.com/blog/11443
- mysql 创建表指定 字符类型与存储引擎
DROP TABLE IF EXISTS apilog; /*==============================================================*/ /* T ...
- BZOJ3750[POI2015]Pieczęć——链表
题目描述 一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色. 你有一个a*b的印章,有些格子是凸起(会沾上墨水)的.你需要判断能否用这个印章印出纸上的图案.印的过程中需要满足以下要求: ...