python装饰器由浅入深
来源:互联网 发布:mysql gtid主从 编辑:程序博客网 时间:2024/05/22 08:04
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
学习装饰器必需要理解装饰器的执行行为,装饰器主要分为无参数的函数、被装饰的函数有参数、装饰器带参数,在原有装饰器的基础上,设置外部变量、装饰器和闭包混用、类装饰器,能正确理解其执行过程即可。下面每种类型给出一个例子,帮助理解:
1:无参数的函数
from time import ctime, sleepdef timefun(func): def wrappedfunc(): print("%s called at %s"%(func.__name__, ctime())) return func() return wrappedfunc@timefundef foo(): print("I am foo")foo()sleep(2)foo()
运行结果:
foo called at Thu Oct 27 14:53:10 2016I am foo#休眠两秒foo called at Thu Oct 27 14:53:12 2016I am foo
这段代码可以理解为:
foo = timefun(foo)#foo先作为参数赋值给func后,foo接收指向timefun返回的wrappedfuncfoo()#调用foo(),即等价调用wrappedfunc()#内部函数wrappedfunc被引用,所以外部函数的func变量(自由变量)并没有释放#func里保存的是原foo函数对象
2:被装饰的函数有参数
from time import ctime, sleepdef timefun(func): def wrappedfunc(a, b): print("%s called at %s"%(func.__name__, ctime())) print(a, b) return func(a, b) return wrappedfunc@timefundef foo(a, b): print(a+b)foo(3,5)sleep(2)foo(2,4)
运行结果:
foo called at Thu Oct 27 15:03:00 2016(3, 5)8foo called at Thu Oct 27 15:03:02 2016(2, 4)6
这段代码可以理解为:
foo = timefun(foo(a,b))#foo先作为参数赋值给func后,foo接收指向timefun返回的wrappedfuncfoo(a,b)#调用foo(),即等价调用wrappedfunc()#内部函数wrappedfunc被引用,所以外部函数的func变量(自由变量)并没有释放#func里保存的是原foo函数对象
3:装饰器带参数,在原有装饰器的基础上,设置外部变量
from time import ctime, sleepdef timefun_arg(pre="hello"): def timefun(func): def wrappedfunc(): print("%s called at %s %s"%(func.__name__, ctime(), pre)) return func() return wrappedfunc return timefun@timefun_arg("world")def foo(): print("I am foo")@timefun_arg("xwp")def too(): print("I am too")foo()sleep(2)foo()too()sleep(2)too()
运行结果:
foo called at Thu Oct 27 15:11:09 2016 worldI am foofoo called at Thu Oct 27 15:11:11 2016 worldI am footoo called at Thu Oct 27 15:11:11 2016 xwpI am tootoo called at Thu Oct 27 15:11:13 2016 xwpI am too
可以理解为:
foo()==timefun_arg("world")(foo)()
4:装饰器和闭包混用
#coding=utf-8from time import timedef logged(when): def log(f, *args, **kargs): print("fun:%s args:%r kargs:%r" %(f, args, kargs)) #%r字符串的同时,显示原有对象类型 def pre_logged(f): def wrapper(*args, **kargs): log(f, *args, **kargs) return f(*args, **kargs) return wrapper def post_logged(f): def wrapper(*args, **kargs): now=time() try: return f(*args, **kargs) finally: log(f, *args, **kargs) print("time delta: %s"%(time()-now)) return wrapper try: return {"pre":pre_logged, "post":post_logged}[when] except KeyError, e: raise ValueError(e), 'must be "pre" or "post"'@logged("post")def fun(name): print("Hello, %s"%(name))fun("hellopython!")
运行结果:
Hello, hellopython!fun:<function fun at 0x10f6078c0> args:('hellopython!',) kargs:{}time delta: 9.98973846436e-05
执行过程:
return {"pre":pre_logged, "post":post_logged}[post]=post_logged,返回post_logged函数,其余与前面类似,自己琢磨一下就理解了。。。
5:类装饰器
class Itcast(object): def __init__(self, func): super(Itcast, self).__init__() self._func = func def __call__(self): print 'class Itcast' self._func() @Itcastdef showpy(): print 'showpy'showpy()
要定义类型的时候,实现call函数,这个类型就成为可调用的。 可以把这个类的对象当作函数来使用。
1 0
- python装饰器由浅入深
- Python装饰器由浅入深
- Python装饰器由浅入深
- 由浅入深理解Python装饰器
- python装饰器由浅入深的学习
- 由浅入深理解装饰器(xinlan course)
- 由浅入深分析python修饰器
- python装饰器装饰类
- [python]python装饰器
- Python装饰器学习
- Python装饰器
- python 装饰器
- Python装饰器
- python 装饰器 应用
- python 装饰器2
- Python装饰器学习
- python装饰器
- python装饰器
- 快速开发工具整理
- Spring AOP动态代理原理与实现方式
- Spark Streaming 数据产生与导入相关的内存分析 数据接收优化
- Shape--使用介绍 4 :椭圆形
- 判断字符串中是否有相同字母
- python装饰器由浅入深
- 关于堆内存和栈内存的简单描述
- B.沼跃鱼
- static
- 数据结构之——基于数组实现的循环队列
- html5跨文档操作
- 输出区间[a , b]内的完数
- js文件校验失败的解决方案
- php中局部变量和全局变量