Python装饰器模式学习总结
装饰器模式,重点在于装饰。装饰的核心仍旧是被装饰对象。
类比于Java编程的时候的包装模式,是同样的道理。虽然概念上稍有不同但是原理上还是比较相近的。下面我就来谈一谈我对Python的装饰器的学习的一点心得吧。
关于作用域
Python作用域 体现在LEGB中:
- L:local 函数内部
- E: enclosing 函数内部和内置函数之间
- G:global 全局性质,有命名空间的限制
- B:build-in 内置函数,由python解释器管理
学过编程的人一眼就可以看得出来大致是什么意思,所以这里不再叙述。
关于闭包
关键在于理解Python中闭包的概念。说白了,闭包就是函数里面又定义了函数,这就是闭包了。(呵呵,断章取义一下。可能说法不恰当)。如下:
def func1():
print 'func1 is running'
def in_func1():
print 'in_func1 is running'
return in_func1
print 'over'
简单的一个闭包的实现,就差不多是这个样子的。我们需要注意的就是要将内部函数当成一个对象来返回(Python中函数其实就是一个对象,我们可以通过type来进行验证)。
这段代码执行的流程是先执行func1,然后执行func2,并且将func2作为一个属性返回给func1.这样我们可以再次的得到func2的内容。这就是闭包!
关于装饰器
类比Java中那么多的模式,比如ServletRequest被装饰成了HttpServletRequest。Python中也有很多这样被装饰的例子。如CookieJar被装饰成了MozillaCookieJar等等。实现的功能就是被装饰对象的功能得到了增强,完成的效果也大大大的比未装饰之前好了。这就是装饰的好处。
下面就来看一看Python中怎么来实现装饰器吧。
核心:借助于@符号,即可。
def bar():
print 'Bar'
@bar
def foo():
print "foo"
# 其等价于:
def foo():
print "foo"
foo = bar(foo)
代码执行的流程:
先执行@对象,也就是一个函数。其返回值就是一个内置函数,只不过这个内置函数是得到了装饰的被装饰对象(这里是foo函数),我们可以理解为:
装饰器,其本身接收一个函数对象作为参数,然后做一些工作后,返回接收的参数,供外界调用。
下面看一个实例:
import time
def function_performance_statistics(trace_this=True):
if trace_this:
def performace_statistics_delegate(func):
def counter(*args, **kwargs):
start = time.clock()
func(*args, **kwargs)
end =time.clock()
print 'used time: %d' % (end - start, )
return counter
else:
def performace_statistics_delegate(func):
return func
return performace_statistics_delegate
@function_performance_statistics(True)
def add(x, y):
time.sleep(3)
print 'add result: %d' % (x + y,)
@function_performance_statistics(False)
def mul(x, y=1):
print 'mul result: %d' % (x * y,)
add(1, 1)
mul(10)
上述代码想要实现一个性能分析器,并接收一个参数,来控制性能分析器是否生效,其运行效果如下所示:
add result: 2
used time: 0
mul result: 10
上述代码中装饰器的调用等价于:
add = function_performance_statistics(True)(add(1, 1))
mul = function_performance_statistics(False)(mul(10))
总结
Python装饰器的核心就是装饰,实质就是被装饰函数性能的增强。
Python装饰器模式学习总结的更多相关文章
- python装饰器的学习笔记
此博文是我对装饰器的一些理解,如果有错误欢迎及时留言,我会第一时间向大家学习. 一.什么是装饰器 1.从字面意义来看: 是用来给函数装饰打扮的函数 2.理论上可以理解为: (1).不改变函数的运行方式 ...
- python 装饰器初步学习
第一步 简单函数 ''' 简单的函数:调用两次''' def myfunc(): print ('myfunc() called.') myfunc() myfunc() 第二步 装饰器为调用函数提供 ...
- Python设计模式-装饰器模式
装饰器模式 装饰器模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活. 代码示例 #coding:utf-8 #装饰器模式 class Beverage(): ...
- 《精通Python设计模式》学习结构型之装饰器模式
这只是实现了Python的装饰器模式. 其实,python的原生的装饰器的应用比这个要强,要广的. ''' known = {0:0, 1:1} def fibonacci(n): assert(n ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- (转载)Python装饰器学习
转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...
- Python装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- ...
- Python 装饰器学习心得
最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数 ...
- 【转】九步学习python装饰器
本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白 ...
随机推荐
- ●洛谷P3168 [CQOI2015]任务查询系统
题链: https://www.luogu.org/problemnew/show/P3168题解: 主席树 强制在线? 那就直接对每一个前缀时间建一个线段树(可持久化线段树),线段树维护优先度权值. ...
- linux内核中的链表
1.内核中的链表 linux内核链表与众不同,他不是把将数据结构塞入链表,而是将链表节点塞入数据,在2.1内核中引入了官方链表,从此内核中所有的链表使用都采用此链表,千万不要在重复造车轮子了!链表实现 ...
- 细胞(cell) 矩阵快速幂
题目描述小 X 在上完生物课后对细胞的分裂产生了浓厚的兴趣.于是他决定做实验并观察细胞分裂的规律.他选取了一种特别的细胞,每天每个该细胞可以分裂出 x 1 个新的细胞.小 X 决定第 i 天向培养皿中 ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- POJ 3045 Cow Acrobats
Description Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away a ...
- 使用PowerPoint
制作PPT在我们的学习生活中非常常见,PPT也就是演示文稿,平时我们在别人演示和讲解一些内容时都需要用到PPT.PPT可以在电脑上进行放映,看上去就好像一张一张的图片,但与图片不同的是它可以进行编辑. ...
- PHP 中 config.m4 的探索
PHP 中 config.m4 的探索 最近在看php扩展相关的东西,虽然来来回回编辑了好多次config.m4,并且也在技术社区看到了 config.m4是什么?什么作用? 类的问题,但是还是觉得有 ...
- jQuery简单笔记
jQuery 是一个 JavaScript 库,简化了 JavaScript 的编程. 语法:$(selector).action() selector 是字符串,表示HTML元素. 对象 符号 例子 ...
- Spring中@Autowired与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必 ...
- 分布式改造剧集之Redis缓存采坑记
Redis缓存采坑记 前言 这个其实应该属于分布式改造剧集中的一集(第一集见前面博客:http://www.cnblogs.com/Kidezyq/p/8748961.html),本来按照顺序 ...