python中的闭包用法实例详解


Posted in Python onMay 05, 2015

本文实例讲述了python中的闭包用法。分享给大家供大家参考。具体分析如下:

什么是闭包?

简单说,闭包就是根据不同的配置信息得到不同的结果

再来看看专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

python实例:

看概念总是让人摸不着头脑,看几个python小例子就会了

例1

def make_adder(addend):
  def adder(augend):
    return augend + addend
  return adder
p = make_adder(23)
q = make_adder(44)
print p(100)
print q(100)

运行结果:

123
144

分析一下:

我们发现,make_adder是一个函数,包括一个参数addend,比较特殊的地方是这个函数里面又定义了一个新函数,这个新函数里面的一个变量正好是外部make_adder的参数.也就是说,外部传递过来的addend参数已经和adder函数绑定到一起了,形成了一个新函数,我们可以把addend看做新函数的一个配置信息,配置信息不同,函数的功能就不一样了,也就是能得到定制之后的函数.

再看看运行结果,我们发现,虽然p和q都是make_adder生成的,但是因为配置参数不同,后面再执行相同参数的函数后得到了不同的结果.这就是闭包.

例2

def hellocounter (name):
  count=[0] 
  def counter():
    count[0]+=1
    print 'Hello,',name,',',str(count[0])+' access!'
  return counter
hello = hellocounter('ma6174')
hello()
hello()
hello()

执行结果

Hello, ysisl , 1 access!
Hello, ysisl , 2 access!
Hello, ysisl , 3 access!

分析一下

这个程序比较有趣,我们可以把这个程序看做统计一个函数调用次数的函数.count[0]可以看做一个计数器,没执行一次hello函数,count[0]的值就加1。也许你会有疑问:为什么不直接写count而用一个列表?这是python2的一个bug,如果不用列表的话,会报这样一个错误:

UnboundLocalError: local variable 'count' referenced before assignment.

什么意思?就是说conut这个变量你没有定义就直接引用了,我不知道这是个什么东西,程序就崩溃了.于是,再python3里面,引入了一个关键字:nonlocal,这个关键字是干什么的?就是告诉python程序,我的这个count变量是再外部定义的,你去外面找吧.然后python就去外层函数找,然后就找到了count=0这个定义和赋值,程序就能正常执行了.

python3 代码

def hellocounter (name):
  count=0 
  def counter():
    nonlocal count
    count+=1
    print 'Hello,',name,',',str(count[0])+' access!'
  return counter
hello = hellocounter('ma6174')
hello()
hello()
hello()

例3

def makebold(fn):
  def wrapped():
    return "<b>" + fn() + "</b>"
  return wrapped
def makeitalic(fn):
  def wrapped():
    return "<i>" + fn() + "</i>"
  return wrapped
@makebold
@makeitalic
def hello():
  return "hello world"
print hello()

执行结果

<b><i>hello world</i></b>

简单分析

怎么样?这个程序熟悉吗?这不是传说的的装饰器吗?对,这就是装饰器,其实,装饰器就是一种闭包,我们再回想一下装饰器的概念:对函数(参数,返回值等)进行加工处理,生成一个功能增强版的一个函数。再看看闭包的概念,这个增强版的函数不就是我们配置之后的函数吗?区别在于,装饰器的参数是一个函数或类,专门对类或函数进行加工处理。

python里面的好多高级功能,比如装饰器,生成器,列表推到,闭包,匿名函数等,开发中用一下,可能会达到事半功倍的效果!

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python用模块pytz来转换时区
Aug 19 Python
Python判断变量是否为Json格式的字符串示例
May 03 Python
python numpy 一维数组转变为多维数组的实例
Jul 02 Python
flask框架实现连接sqlite3数据库的方法分析
Jul 16 Python
使用Python实现在Windows下安装Django
Oct 17 Python
使用python list 查找所有匹配元素的位置实例
Jun 11 Python
Python爬虫实现的根据分类爬取豆瓣电影信息功能示例
Sep 15 Python
在python3.64中安装pyinstaller库的方法步骤
Jun 02 Python
Pycharm安装Qt Design快捷工具的详细教程
Nov 18 Python
python用分数表示矩阵的方法实例
Jan 11 Python
两行代码解决Jupyter Notebook中文不能显示的问题
Apr 24 Python
分享7个 Python 实战项目练习
Mar 03 Python
Python闭包实现计数器的方法
May 05 #Python
深入探究Python中变量的拷贝和作用域问题
May 05 #Python
Python使用metaclass实现Singleton模式的方法
May 05 #Python
python中查看变量内存地址的方法
May 05 #Python
Python中统计函数运行耗时的方法
May 05 #Python
Python调用命令行进度条的方法
May 05 #Python
Python记录详细调用堆栈日志的方法
May 05 #Python
You might like
PHP中break及continue两个流程控制指令区别分析
2011/04/18 PHP
php中用数组的方法设置cookies
2011/04/21 PHP
将时间以距今多久的形式表示,PHP,js双版本
2012/09/25 PHP
thinkPHP简单遍历数组方法分析
2016/05/16 PHP
CI框架数据库查询缓存优化的方法
2016/11/21 PHP
替换php字符串中的单引号为双引号的方法
2017/02/16 PHP
PHP检测一个数组有没有定义的方法步骤
2019/07/20 PHP
默认让页面的第一个控件选中的javascript代码
2009/12/26 Javascript
javascript设计模式 接口介绍
2012/07/24 Javascript
asp.net中System.Timers.Timer的使用方法
2013/03/20 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
2015/10/01 Javascript
深入解析Javascript闭包的功能及实现方法
2016/07/10 Javascript
JS高仿抛物线加入购物车特效实现代码
2017/02/20 Javascript
浅谈jquery拼接字符串效率比较高的方法
2017/02/22 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
vue 音乐App QQ音乐搜索列表最新接口跨域设置方法
2018/09/25 Javascript
Angular父子组件通过服务传参的示例方法
2018/10/31 Javascript
微信小程序如何获取群聊的openGid以及名称详解
2019/07/17 Javascript
[52:03]Secret vs VG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python实现apahce网站日志分析示例
2014/04/02 Python
python去除所有html标签的方法
2015/05/05 Python
python+ffmpeg视频并发直播压力测试
2018/03/06 Python
python装饰器深入学习
2018/04/06 Python
python使用插值法画出平滑曲线
2018/12/15 Python
keras tensorflow 实现在python下多进程运行
2020/02/06 Python
python词云库wordCloud使用方法详解(解决中文乱码)
2020/02/17 Python
css3实现背景颜色渐变让图片不再是唯一的实现方式
2012/12/18 HTML / CSS
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
潘多拉珠宝美国官方网站:Pandora US
2020/06/18 全球购物
程序员机试试题汇总
2012/03/07 面试题
教师实习自我鉴定
2013/12/11 职场文书
公司门卫工作职责
2014/06/28 职场文书
合法的离婚协议书范本
2014/10/23 职场文书
党的群众路线教育实践活动心得体会(企业)
2014/11/03 职场文书
领导莅临指导欢迎词
2015/09/30 职场文书