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 拷贝对象(深拷贝deepcopy与浅拷贝copy)
Sep 06 Python
Python2中的raw_input() 与 input()
Jun 12 Python
Python脚本获取操作系统版本信息
Dec 17 Python
Python numpy生成矩阵、串联矩阵代码分享
Dec 04 Python
使用Python更换外网IP的方法
Jul 09 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
Python 实现子类获取父类的类成员方法
Jan 11 Python
pybind11在Windows下的使用教程
Jul 04 Python
python实现在一个画布上画多个子图
Jan 19 Python
Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作
Jun 06 Python
python+requests实现接口测试的完整步骤
Oct 27 Python
详解Python函数print用法
Jun 18 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+Mysql+jQuery实现发布微博程序 jQuery篇
2011/10/08 PHP
PHP代码优化的53个细节
2014/03/03 PHP
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
2017/05/30 PHP
PHP实现PDO操作mysql存储过程示例
2019/02/13 PHP
JAVASCRIPT IE 与 FF中兼容问题小结
2009/02/18 Javascript
JavaScript中的面向对象介绍
2012/06/30 Javascript
javascript调试之DOM断点调试法使用技巧分享
2014/04/15 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
2014/06/26 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
基于Vue2实现的仿手机QQ单页面应用功能(接入聊天机器人 )
2017/03/30 Javascript
vue异步axios获取的数据渲染到页面的方法
2018/08/09 Javascript
详解vue使用插槽分发内容slot的用法
2019/03/28 Javascript
vue指令做滚动加载和监听等
2019/05/26 Javascript
react 生命周期实例分析
2020/05/18 Javascript
vue3为什么要用proxy替代defineProperty
2020/10/19 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
2020/11/17 Vue.js
[01:01]青春无憾,一战成名——DOTA2全国高校联赛开启
2018/02/25 DOTA
用Python登录好友QQ空间点赞的示例代码
2017/11/04 Python
Python Opencv任意形状目标检测并绘制框图
2019/07/23 Python
Python银行系统实战源码
2019/10/25 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
jupyter notebook 参数传递给shell命令行实例
2020/04/10 Python
jenkins+python自动化测试持续集成教程
2020/05/12 Python
Python同时处理多个异常的方法
2020/07/28 Python
appium+python自动化配置(adk、jdk、node.js)
2020/11/17 Python
2分钟教你实现环形/扇形菜单(基础版)
2020/01/15 HTML / CSS
html+css3实现的登录界面
2020/12/09 HTML / CSS
芝加哥牛排公司:Chicago Steak Company
2018/10/31 全球购物
机电专业个人自荐信格式模板
2013/09/23 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
世界读书日的活动方案
2014/08/20 职场文书
python 爬取豆瓣网页的示例
2021/04/13 Python
MySQL慢查询中的commit慢和binlog中慢事务的区别
2022/06/16 MySQL
MySQL深分页问题解决思路
2022/12/24 MySQL