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. [Leetcode] Longest Substring Without Repeating Characters (C++)

    题目: Given a string, find the length of the longest substring without repeating characters. For examp ...

  2. css布局学习笔记之max-width

    设置块级元素的 width 可以阻止它从左到右撑满容器.然后你就可以设置左右外边距为 auto 来使其水平居中.元素会占据你所指定的宽度,然后剩余的宽度会一分为二成为左右外边距. div{ width ...

  3. 读取xml文件转成List<T>对象的两种方法(附源码)

    读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...

  4. Ubuntu安装字体的方法

    基本步骤如下: 1. 将要安装的字体放在一个文件夹下,以/home/UsrName/Download/Font为例 2.在终端中输入 sudo cp -r /home/UsrName/Download ...

  5. 工作中小知识点汇总(sql)

    1.with(nolock) 在查询表的时候加上它可以增加33%查询效率 例子:SELECT TOP 5 b.UserName,f.issuedDate,r.tktedTime,r.refundSig ...

  6. 学习Emacs

    1.http://ergoemacs.org/emacs/emacs.html 2.Debian7安装emacs24 http://my.oschina.net/xuzhouyu/blog/14954 ...

  7. 前端MVVM学习之KnockOut(一)

    MVVM理解 MVVM即Model-View-viewModel,是微软WPF和MVP(Model-View-Presenter)结合发展演变过来的一种新型架构框架. MVVM设计模式有以下优点: ( ...

  8. Linux释放内存

    在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好.但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了. ...

  9. \s+(?<request_time>\d+(?:\.\d+)?)\s+ 解释

    <pre name="code" class="html"><pre name="code" class="ht ...

  10. hdu 4619 Warm up 2 ( 二分图最大匹配 )

    题目:Warm up 2 题意:有横竖两种方式放着的多米诺骨牌,相同方向的不可能重叠,但是横放和竖放             的牌可能重叠.移走重叠的牌使剩下的牌最多. 分析:二分图匹配:最大独立集= ...