装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
假如我要计算一个函数的执行时间:
import time
def foo():
print 'in foo()'
def timeit(func):
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
timeit(foo)
计算完一个之后,我又想计算其它几个函数的执行时间,为了避免重复写类似的函数,就可以让装饰器来帮你解决这个问题。
import time
def timeit(func):
def wrapper():
start = time.clock()
func()
end = time.clock()
print ‘used’,end - start
return wrapper
@timeit
def function():
print 'into function()'
function()
-----------------------------------
使用内嵌包装函数来确保每次新函数都被调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# '''示例4: 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象''' def deco(func): def _deco(): print ( "before ) func() print ( " ) # return _deco @deco def myfunc(): print ( " ) return 'ok' myfunc() myfunc() |
对带参数的函数进行装饰
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# '''示例5: 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象''' def deco(func): def _deco(a, print ( "before ) ret = func(a, print ( " % ret) return ret return _deco @deco def myfunc(a, print ( " % (a, return a + b myfunc( 1 , 2 ) myfunc( 3 , 4 ) |
对参数数量不确定的函数进行装饰
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# '''示例6: 参数用(*args, def deco(func): def _deco( * args, * * kwargs): print ( "before % func.__name__) ret = func( * args, * * kwargs) print ( " % (func.__name__, return ret return _deco @deco def myfunc(a, print ( " % (a, return a + b @deco def myfunc2(a, print ( " % (a, return a + b + c myfunc( 1 , 2 ) myfunc( 3 , 4 ) myfunc2( 1 , 2 , 3 ) myfunc2( 3 , 4 , 5 ) |
让装饰器带参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# '''示例7: 和上一示例相比在外层多了一层包装。 装饰函数名实际上应更有意义些''' def deco(arg): def _deco(func): def __deco(): print ( "before % (func.__name__, func() print ( " % (func.__name__, return __deco return _deco @deco ( "mymodule" ) def myfunc(): print ( " ) @deco ( "module2" ) def myfunc2(): print ( " ) myfunc() myfunc2() |