Python闭包

先看一个例子:

def outer(x):
def inner(y):
return x+y
return innder add = outer(8)
print add(6)

我们定义了一个方法outer,方法内部又定义了一个方法inner,方法outer返回值为内部定义的方法inner。

同时,内部方法innder使用了外部方法的参数x。

从我们的调用方式可以清晰地看到,add=outer(8)相当于add接受了类似于下边一个方法

def inner(y):
return 8+y

然后调用add(6),结果显示14

这其实就是一个简单的闭包。

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

下边是另一个闭包的实例--方法作为参数传递

def tsfunc(func,x):
def wrappedFunc():
print func.__name__
return func(x)
return wrappedFunc() def foo(x):
print 'aaa' + x if __name__=='__main__':
tsfunc(foo , "x")

结果是:

foo
aaax

我们把方法foo当做参数传递到另一个方法tsfunc内,然后在tsfunc内做了其他一些事情(这里我们只是打印了foo的name),最后又返回来foo,并使用了额外参数。

装饰器

不带参数的装饰器

和上边一样,举个例子,如下:

def decorator(F):
def new_F(a, b):
print "input", a, b
return F(a, b)
return new_F @decorator
def sub(a,b):
return a-b def add(a,b):
return a+b print sub(3,4) add = decorator(add)
print add(3, 4)

结果如下:

input 3 4
-1
input 3 4
7

对比sub的调用和add的调用,其实他们是完全一样的运行方式,只不过装饰器将语法包裹起来,看起来更干净一些。

或许你现在发现一个问题,如果我们要给装饰器加参数,在被装饰的方法内部使用该怎么做呢?

装饰器工厂(带参数的装饰器)

在装饰器基础上再增加一层嵌套,其定义和实现装饰器是一样的,看下边的例子:

# a new wrapper layer
def pre_str(pre=''):
# old decorator
def decorator(F):
def new_F(a, b):
print(pre + "input", a, b)
return F(a, b)
return new_F
return decorator @pre_str('^_^')
def sub(a,b):
return a-b def add(a,b):
return a+b print sub(3,4) dec = pre_str('&_&')
add = dec(add)
print add(3, 4)

这个也是很好理解的了吧,我们的装饰运行方式和分步调用是同一个效果的。

这样就实现了装饰器语法传递参数,效果还不错。

类装饰器

看下边例子:

def decorator(aClass):
class newClass:
def __init__(self, age):
self.total_display = 0
self.wrapped = aClass(age)
def display(self):
self.total_display += 1
print "total display:%s" % self.total_display
self.wrapped.display()
return newClass @decorator
class Bird:
def __init__(self, age):
self.age = age
def display(self):
print "My age is %s"% self.age eagleLord = Bird(5)
for i in range(3):
eagleLord.display()

运行结果:

定义了decorator作用给类Bird,当初始化Bird类时,装饰器会先进行初始化,使用Bird初始化的参数,然后返回一个装饰器内定义的类。

例子中装饰器内的类包裹了一个Bird类实例,并实例化。根据单步调试来看,Bird类初始化只进行了一次,即相当于Bird的初始化时在装饰器内被调用生成实例时调用的。

要注意的是:Bird(5)的返回值并不是Bird实例,而是装饰器内的类newClass实例

那么剩下的就是很简单的方法调用了。

Python闭包及装饰器的更多相关文章

  1. python 闭包和装饰器

    python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...

  2. python闭包与装饰器

    转自小马哥: 闭包和装饰器充分体现了Python语法糖的优雅感觉. 在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写: def valida ...

  3. 高逼格利器之Python闭包与装饰器

    生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...

  4. Python—闭包和装饰器

    闭包 定义:内部函数对外部函数变量的引用,则将该函数与用到的变量称为闭包. 闭包必须满足以下三个条件: 必须有一个内嵌函数. 内嵌函数必须引用外部函数中的变量. 外部函数返回值必须是内嵌函数的引用. ...

  5. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  6. python闭包以及装饰器

    通俗的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变 ...

  7. python闭包和装饰器

    本文目录: 1. 闭包的解析和用法 2. 函数式装饰器 3. 类装饰器 一.闭包 闭包是一种函数,从形式上来说是函数内部定义(嵌套)函数,实现函数的扩展.在开发过程中,考虑到兼容性和耦合度问题,如果想 ...

  8. python闭包和装饰器(转)

    一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... prin ...

  9. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

随机推荐

  1. Excel Aspose.Cells 设置单元格格式 为数字

    Workbook workbook = new Workbook(); //工作簿 Worksheet sheet = workbook.Worksheets[]; //工作表 sheet.Cells ...

  2. Advanced Fruits(HDU 1503 LCS变形)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. LigerUI 分页 MVC

    Javascirpt代码 $("#showData").ligerGrid({ columns: [ { display: '编号', name: 'L_ID', align: ' ...

  4. cxf2.7.10与Spring3.0.5集成时报错如下

    严重: Error listenerStart 2014-3-29 22:25:20 org.apache.catalina.core.StandardContext start 严重: Contex ...

  5. BZOJ 1064 假面舞会

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 思路:第一眼看的时候以为是差分约束,但是是做不了的,不过能保证的就是这题绝对是图论题...(废 ...

  6. Material风格的Quick组件,妈妈再也不用担心我的界面不好看了

    https://github.com/papyros/qml-material http://www.zhihu.com/question/38523930

  7. Window运行命令大全

    1. gpedit.msc-----组策略    2. sndrec32-------录音机   3. Nslookup-------IP地址侦测器   4. explorer-------打开资源管 ...

  8. codeforce343A

    题目地址:http://codeforces.com/problemset/problem/343/A 比赛的时候就囧了,只推出a<b的时候最少需要b个电阻. 后来看了题解,知道 题意:用最少的 ...

  9. 开源欣赏wordpress之intall.php

    引导式安装 $weblog_title = isset( $_POST['weblog_title'] ) ? trim( wp_unslash( $_POST['weblog_title'] ) ) ...

  10. 在 ASP.NET MVC 项目中使用 WebForm、 HTML

    原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...