Python闭包的高级应用-装饰器的实现
我们先看一个闭包的例子:
from time import ctime def before_call(f):
def wrapped(*args, **kargs):
print 'before calling, now is %s' % ctime()
return f(*args, **kargs)
return wrapped def test(name):
print 'hello, %s' % (name) if __name__ == '__main__':
before_call(test)("lucky")
我们先看运行结果:
~/Documents/py python 2.py
before calling, now is Sat Dec 27 21:30:18 2014
hello, lucky
上面的代码使用了闭包,因为子函数wrapped将父函数的内部变量f与之绑定。
这样,wrapped这个闭包函数,实际上先打印时间,然后调用f,所以正如结果打印的一般,before_call起到的是一种装饰的作用。
这里我扩展它的功能,增加一个调用函数后,打印时间:
from time import ctime def before_call(f):
def wrapped(*args, **kargs):
print 'before calling, now is %s' % ctime()
return f(*args, **kargs)
return wrapped def after_call(f):
def wrapped(*args, **kargs):
try:
return f(*args, **kargs)
finally:
print 'after calling, now is %s' % ctime()
return wrapped def test(name):
print 'hello, %s' % (name) if __name__ == '__main__':
before_call(test)("lucky")
after_call(test)("peter")
before_call(after_call(test))("john")
after_call(before_call(test))('marry')
运行结果为:
~/Documents/py python 2.py
before calling, now is Sat Dec 27 21:37:24 2014
hello, lucky
hello, peter
after calling, now is Sat Dec 27 21:37:24 2014
before calling, now is Sat Dec 27 21:37:24 2014
hello, john
after calling, now is Sat Dec 27 21:37:24 2014
before calling, now is Sat Dec 27 21:37:24 2014
hello, marry
after calling, now is Sat Dec 27 21:37:24 2014
运行结果是正确的。注意最后两个,顺序交换了,对结果无影响。
下面我们再包装一层:
def after_call():
def after(f):
def wrapped(*args, **kargs):
try:
return f(*args, **kargs)
finally:
print 'after calling, now is %s' % ctime()
return wrapped
return after def before_call():
def before(f):
def wrapped(*args, **kargs):
print 'before calling, now is %s' % ctime()
return f(*args, **kargs)
return wrapped
return before
那么如何使用呢?这里就是python装饰器的语法,
如果我们这样使用:
@before_call()
def test(name):
print 'hello, %s' % (name) if __name__ == '__main__':
test("lucky")
注意test函数前加了装饰的符号。
还可以这样:
@after_call()
def test(name):
print 'hello, %s' % (name)
甚至可以嵌套多层:
@before_call()
@after_call()
def test(name):
print 'hello, %s' % (name)
这就是python中装饰器的原理,内部采用了闭包。
Python闭包的高级应用-装饰器的实现的更多相关文章
- python高级之装饰器
python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...
- 第二篇:python高级之装饰器
python高级之装饰器 python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...
- python中函数总结之装饰器闭包
1.前言 函数也是一个对象,从而可以增加属性,使用句点来表示属性. 如果内部函数的定义包含了在外部函数中定义的对象的引用(外部对象可以是在外部函数之外),那么内部函数被称之为闭包. 2.装饰器 装饰器 ...
- 简学Python第四章__装饰器、迭代器、列表生成式
Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群 群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...
- Python全栈开发之---装饰器
1.装饰器的形成过程 import time def func1(): print('in func1') def timer(func): def inner(): start = time.tim ...
- 初学 Python(十五)——装饰器
初学 Python(十五)--装饰器 初学 Python,主要整理一些学习到的知识点,这次是生成器. #-*- coding:utf-8 -*- import functools def curren ...
- 十一. Python基础(11)—补充: 作用域 & 装饰器
十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...
- Python 函数修饰符(装饰器)的使用
Python 函数修饰符(装饰器)的使用 1. 修饰符的来源修饰符是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等. 修饰符是解决这类问题的绝佳设计, ...
- Python 标准库中的装饰器
题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...
随机推荐
- 架设Hmailserver+webmail邮件服务器
架设Hmailserver+webmail邮件服务器 在安裝Hmailserver前先安裝Apache.php.mysql,如果你想懶點直接到http://www.phpnow.org下載phpn ...
- 离线安装docker最新版,记得要以下三个包。
如果安装了以前版本,还要删除以下这个包. container-selinux.noarch 2:2.10-2.el7 ============== 离线安装三个rpm -rw-r--r--. 1 ro ...
- 【互动问答分享】第10期决胜云计算大数据时代Spark亚太研究院公益大讲堂
“决胜云计算大数据时代” Spark亚太研究院100期公益大讲堂 [第10期互动问答分享] Q1:Spark on Yarn的运行方式是什么? Spark on Yarn的运行方式有两种:Client ...
- Spark部署及应用
在飞速发展的云计算大数据时代,Spark是继Hadoop之后,成为替代Hadoop的下一代云计算大数据核心技术,目前Spark已经构建了自己的整个大数据处理生态系统,如流处理.图技术.机器学习.NoS ...
- Django+ openpyxl 导出文件,设置表头/内容格式
之前使用xlrd.xlrt处理文件的导入导出,这两个主要用于excel2003格式的文件的读写,并且xlrt最多可以写入256行,大于256行会报错 找了新插件openpyxl,对它找到针对某一行设置 ...
- HDU 1811 Rank of Tetris 【拓扑排序 + 并查集】
自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜, ...
- [Python Debug]Kernel Crash While Running Neural Network with Keras|Jupyter Notebook运行Keras服务器宕机原因及解决方法
最近做Machine Learning作业,要在Jupyter Notebook上用Keras搭建Neural Network.结果连最简单的一层神经网络都运行不了,更奇怪的是我先用iris数据集跑了 ...
- MySql笔记之数据表
数据表:行称为记录 列称为字段 用来存储数据 一.数据类型 数据类型是指列.存储过程参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. 在我们存储不同类型的数据时,为了 ...
- 20、Flask实战第20天:Flask上下文
Local线程隔离对象 我们知道通过request可以获取表单中的数据.如果是多个用户同时在用网站,而全局request就只有一个,那么Flask是如何分辨哪用户对应哪个请求呢? 这种情况下,就会用到 ...
- 【权值分块】bzoj3224 Tyvj 1728 普通平衡树
权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...