Python---装饰器,python---装饰
Python---装饰器,python---装饰
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
假如我要计算一个函数的执行时间:
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 |
#
-*- coding:gbk -*-
'''示例4:
使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
def _deco():
print ( "before
myfunc() called." )
func()
print ( "
after myfunc() called." )
#
不需要返回func,实际上应返回原函数的返回值
return _deco
@deco
def myfunc():
print ( "
myfunc() called." )
return 'ok'
myfunc()
myfunc()
|
对带参数的函数进行装饰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#
-*- coding:gbk -*-
'''示例5:
对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
def deco(func):
def _deco(a,
b):
print ( "before
myfunc() called." )
ret
= func(a,
b)
print ( "
after myfunc() called. result: %s" % ret)
return ret
return _deco
@deco
def myfunc(a,
b):
print ( "
myfunc(%s,%s) called." % (a,
b))
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 |
#
-*- coding:gbk -*-
'''示例6:
对参数数量不确定的函数进行装饰,
参数用(*args,
**kwargs),自动适应变参和命名参数'''
def deco(func):
def _deco( * args,
* * kwargs):
print ( "before
%s called." % func.__name__)
ret
= func( * args,
* * kwargs)
print ( "
after %s called. result: %s" % (func.__name__,
ret))
return ret
return _deco
@deco
def myfunc(a,
b):
print ( "
myfunc(%s,%s) called." % (a,
b))
return a + b
@deco
def myfunc2(a,
b, c):
print ( "
myfunc2(%s,%s,%s) called." % (a,
b, c))
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 |
#
-*- coding:gbk -*-
'''示例7:
在示例4的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''
def deco(arg):
def _deco(func):
def __deco():
print ( "before
%s called [%s]." % (func.__name__,
arg))
func()
print ( "
after %s called [%s]." % (func.__name__,
arg))
return __deco
return _deco
@deco ( "mymodule" )
def myfunc():
print ( "
myfunc() called." )
@deco ( "module2" )
def myfunc2():
print ( "
myfunc2() called." )
myfunc()
myfunc2()
|
所谓装饰器就是把函数包装一下,为函数添加一些附加功能,装饰器就是一个函数,参数为被包装的函数,返回包装后的函数:你可以试下:
def d(fp): def _d(*arg, **karg): print "do sth before fp.." r= fp(*arg, **karg) print "do sth after fp.." return r return _d@ddef f(): print "call f"#上面使用@d来表示装饰器和下面是一个意思#f = d(f)f()#调用f
不知道,可能不能在装饰器跳出主函数吧
评论暂时关闭