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. Asp.Net通过SignalR实现IM即时通讯

    前言:SignalR是一种针对H5中WebSocket的解决方案,可以实现在不支持H5的浏览器中实现IM 后端: step 1:通过NuGet安装SignalR step 2:新建一个类继承于Hub, ...

  2. VM11里安装ubuntukylin-16.04-desktop-amd64遇到问题

    一.ubuntu linux的地址 http://www.ubuntu-china.cn/ 这个地址是中国站,点击下载菜单后,有两个版本,一个是ubuntu,一个是kylin.后者是专门加了中文程序的 ...

  3. PROCEDURE_监测系统_告警信息存储过程—产生告警信息插入告警表

    create or replace procedure proc_alarmlog(in_id   in number, --采集器编码                                 ...

  4. Eclipse中设置条件断点

    1.在要添加断点的变量那一行前双击,添加断点: 2.在该断点处点击鼠标右键,在弹出的选项卡中选择“断点属性”Breakpoint Properties; 3.在断点属性选项卡中勾选Enabled复选框 ...

  5. C# 语法技巧_三目运算_switch_case

    一.三目运算符 三目运算符的一种简便写法: bool b = str == "abc" ? false : true; 当是自身时,实际上别吝啬那一个括号,有一个括号,实际上更容易 ...

  6. 数据可视化的优秀入门书籍有哪些,D3.js 学习资源汇总

    习·D3.js 学习资源汇总 除了D3.js自身以外,许多可视化工具包都是基于D3开发的,所以对D3的学习就显得很重要了,当然如果已经有了Javascript的经验,学起来也会不费力些. Github ...

  7. WebGL 初探

    官方网站:http://webglfundamentals.org/ WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenG ...

  8. 【剑指offer】面试题22:栈的压入、弹出序列

    题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列 ...

  9. Kth Smallest Element in a BST 解答

    Question Given a binary search tree, write a function kthSmallest to find the kth smallest element i ...

  10. Yii2 框架下bootstrap 弹窗预览视频等~

    Yii2 本身已经引用了'yii\bootstrap\BootstrapAsset',所以使用bootstrap 非常简洁. 1 在PHP页面引用命名空间 use app\assets\AppAsse ...