转自:http://www.cnblogs.com/ma6174/archive/2013/04/15/3022548.html


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()

关于这个问题的研究您可以参考http://linluxiang.iteye.com/blog/789946

例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中的闭包的更多相关文章

  1. 说说Python中的闭包 - Closure

    转载自https://segmentfault.com/a/1190000007321972 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西 ...

  2. 说说Python中的闭包

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  3. Python中的闭包 - Closure

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  4. 21.python中的闭包和装饰器

    python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...

  5. 轻松理解python中的闭包和装饰器 (下)

    在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...

  6. 轻松理解python中的闭包和装饰器(上)

    继面向对象编程之后函数式编程逐渐火起来了,在python中也同样支持函数式编程,我们平时使用的map, reduce, filter等都是函数式编程的例子.在函数式编程中,函数也作为一个变量存在,对应 ...

  7. Python 中的闭包

    通常来说,函数中的局部变量在函数调用结束的时候不能再被引用,所分配的空间也会被回收. 但是通过闭包这种技术,函数调用结束了,它的局部变量的值还可以保存在闭包里. 试举一例: def make_adde ...

  8. 聊聊Python中的闭包和装饰器

    1. 闭包 首先我们明确一下函数的引用,如下所示: def test1(): print("--- in test1 func----") # 调用函数 test1() # 引用函 ...

  9. python中的闭包与装饰器

    #原创,转载请留言联系 装饰器的本质就是闭包,所以想知道装饰器是什么,首先要理解一下什么是闭包. 闭包 1. 外部函数返回内部函数的引用.2. 内部函数使用外部函数的变量或者参数. def outer ...

随机推荐

  1. Python程序中的进程操作-进程同步(multiprocess.Lock)

    目录 一.多进程抢占输出资源 二.使用锁维护执行顺序 三.多进程同时抢购余票 四.使用锁来保证数据安全 通过刚刚的学习,我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的 ...

  2. Spring 中AOP及前后置增强案例

    1.AOP面向切面编程 面向切面编程的本质:面向切面编程,指扩展功能不修改源代码,将功能代码从业务逻辑代码中分离出来.  1主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等.  2主要意 ...

  3. selenium三大切换的骚操作之显性等待

    一.handle窗口切换 当点击某个元素后,会重新生成一个新的页签,但此时我们的操作仍然在原先的窗口当中,如果要在新的窗口继续操作元素,那么就要用到handle窗口切换的方法. 常用方法: windo ...

  4. PHP TP框架自定义打印函数P

    效果如下,有个灰色背景,也不一定是灰色可以改 代码: //传递数据以易于阅读的样式格式化后输出function p($data){ // 定义样式 $str='<pre style=" ...

  5. My97Datepicker 日历控件的使用

    如果显示中乱码可以再改变lang  js包 中的  以防乱码 var $lang = {errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\ ...

  6. 20个Python代码段,你需要立刻学会,好用到哭!

    Python是一种非BS编程语言.设计简单和易读性是它广受欢迎的两大原因.正如Python的宗旨:美丽胜于丑陋,显式胜于隐式. 记住一些帮助提高编码设计的常用小诀窍是有用的.在必要时刻,这些小诀窍能够 ...

  7. django4-模板进阶

    1.模板系统的语法 引用变量数据: {{  }} 标签逻辑操作:{%...%} 2.变量 变量名由字符数字下划线组成 ,可以执行由视图函数传过来的对象的方法和属性 ,但是视图函数中如果使用 ' . ' ...

  8. IDEA下新建Vue项目

    1.首先需要安装nodeJS,并配置全局环境变量. 2.在IDEA中新建一个空的project 3.在setting中配置JavaScript的语言版本为6 在file types的html中添加.* ...

  9. 8.python3实用编程技巧进阶(三)

    3.1.如何实现可迭代对象和迭代器对象 #3.1 如何实现可迭代对象和迭代器对象 import requests from collections.abc import Iterable,Iterat ...

  10. ubuntu 查看软件包中的内容 (已经安装)

    在 使用 apt 进行安装软件的时候,我们要经常判断,软件安装了什么和安装到什么地方.这时候 我们要使用 dpkg -L 命令来进行查看: 同样 在 fedora 上可以使用 rpm -ql iper ...