您的位置:首页 > 编程语言 > Python开发

python装饰器理解

2015-05-25 17:58 155 查看
本文转载

原作者:sky

链接:http://blog.csdn.net/a8572785/article/details/12947359

首先感谢团队的Leno、Damon、以及Joel,是他们让我接触到这个实用的知识点!装饰器是一个著名的设计模式,常用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

比如:要查看一段程序的执行时间:以往我会在代码前后加入starTime 、endTime来处理;后来觉得在每段代码的前后加代码显得重复累赘,于是创建了一个时间器函数如:timeIt(fn),再将要查看程序执行时间的那段代码也包装成函数,然后将它与参数的形式传递给timeIt()

在相当长的一段时间内,我以为自己这样处理算得上是一个创举,起码一个函数就可以搞定,而不用在每段要检测的代码前后重复插入了吧!直到前些日子项目要求,Leno、Damon向我提到勾子函数与装饰器,才知道有更科学高效的方法进行事务处理!同时感谢Joel,曾经向他讨教过如何有效记录系统运行时间问题时,是他向我道出这个“装饰模式”这个设计模式!那么是如何做的呢?

对于查看运行时间,原来我的思路是:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import time

def sayHi():

print "hello world!"

def timeit(fn):

startTime = time.time()

fn()

endTime = time.time()

print endTime - startTime

timeit(sayHi)

 
原来的sayHi()被修改成timeit(saiHi),sayHi作为参数传递了。

那么,装饰模式的思路是:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import time

def timeit(fn):

def wraper():

startTime = time.time()

fn()

endTime = time.time()

print endTime - startTime

return wraper

def sayHi():

print "hello world!"

sayHi= timeit(sayHi)

sayHi()
在sayHi()前加入sayHi = timeit(sayHi),进行计时处理,但timeit(sayHi)并不是直接产生调用效果,而是返回一个函数赋值给sayHi! sayHi()调用并没有像我原先的思路那样被修改了,可此sayHi()已非彼sayHi()。

这种在某段代码的前后需要加入一点额外的处理时,这种编程方式被称为面向切面的编程(AOP),而对于什么是装饰器,什么是面向切面编程可以阅读下面这篇好文章:

Python装饰器学习 :/article/1973855.html

Python装饰器与面向切面编程:/article/5268067.html

如果你还没有阅读《Python装饰器与面向切面编程》,那么你一定也认为在sayHi()前加入的这句 sayHi = timeit(sayHi) 已经是无可挑剔了!其实,它还是可以再优化的!这就是我的队友Leon提到的勾子函数!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import time

def timeit(fn):

def wraper():

startTime = time.time()

fn()

endTime = time.time()

print endTime - startTime

return wraper

@timeit

def sayHi():

print "hello world!"

sayHi()
看到了吧?仅仅是在def saiHi()前增加一句@timeit,它却等同于sayHi = timeit(sayHi)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: