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 ...
随机推荐
- Delphi - 字符串 详解
来自:http://www.cnblogs.com/huangjacky/archive/2009/12/10/1620950.html ------------------------------- ...
- centos 查看 arp
yum install tcpdump -y tcpdump arp :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: :: ...
- 将datatable导出为excel的三种方式(转)
一.使用Microsoft.Office.Interop.Excel.DLL 需要安装Office 代码如下: 2 public static bool ExportExcel(Sy ...
- java.io.WriteAbortedException异常
java.io.WriteAbortedException异常 未实现 public interface Serializable 接口的类将无法使其任何状态序列化或反序列化. 可序列化类的所有子类型 ...
- 虚拟机Visualbox安装Ubuntu Server
关于虚拟机的新建及设置,请查看<Visualbox安装Ubuntu网络设置> 从光盘启动系统中,首先是选择语言,我这里选择英文 选择英文安装Ubuntu服务器 继续选择英文 选择地理位置, ...
- circusctl命令在ubuntu 上执行,卡住的现象处理。
1. circus介绍 circus是一个进程管理工具,类似于supervisod. 2. circusctl是circusd进程的管理工具 3. circus的安装 pip3 install cir ...
- 11、Flask实战第11天:蓝图
蓝图的基本使用 之前我们写的代码都是集中在一个主程序文件里面.这样不利于分层解耦和维护.蓝图的作用就是让我们的flask项目更加模块化结构更加清晰,可以将相同模块的视图函数放在同一个蓝图下,同一个文件 ...
- python3 开发面试题(%s和format的区别)5.31
在格式化字符串中有两种方法: 1.%s 2.format 大家常用的是哪一种方法?为什么要用你选的这种方法? 我们先看一个例子: 首先我们定义一个我军需要击杀的恐怖分子的地理坐标为 c=(128,12 ...
- iOS 10 资料整理笔记
1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserN ...
- web 中加载配置文件
1.web.xml中配置 <!-- 加载配置文件 --> <listener> <description>ServletContextListen ...