增加计时检测性能;
给函数增加事务能力,在不改动原函数的情况下,增加该函数额外的功能
语法
装饰器就是把其他函数作为参数的函数;
装饰器以@开头,紧接着是装饰器的名字,然后是是被修饰的函数和装饰函数的可选参数,格式如下
@decorator
def fun(fun_arg):
….
类中的静态方法和类方法就是典型的装饰器的应用。
多个装饰器
@dec2
@dec1
def fun():
pass
等价于:dec2(dec1(func))
直白些- -!
- 装饰器就是函数A调用了函数B,然后函数B调用了函数C,然后函数C调用了函数D…….;
- 有装饰器的函数中的参数列表就是为最后一层装饰器返回的函数(也就是最顶层的装饰器返回的函数)所准备的;
有参数和无参数的装饰器
无参数
格式:
@dec
def fun():pass
等价于fun = dec(fun)
简单例子
def decorate2(func2):
def f2():
print "hot"
func2()
return f2
def decorate1(func1):
def f1():
print "little"
func1()
return f1
@decorate2
@decorate1
def water():
print 'water'
@decorate1
def coke():
print 'coke'
water() #result: hot little water
coke() #result: little coke
- water() = decorate2(decorate1(water))()
- decorate2(decorate1(water))() = decorate2(f1)(),此时func1 = water
- decorate2(f1)() = f2(),此时fun2 = f1
- 执行f2(),然后执行f1()
- 然后执行water()
有参数
格式:
@dec2(args)
@dec1
def fun():pass
等价于fun = dec2(args)(dec1(fun))
简单例子
def decorate2(func2):
def f2(num):
print "hot",num
func2(num + 1)
return f2
def decorate1(func1):
def f1(num):
print "little",num
func1(num + 1)
return f1
@decorate1
def coke(num):
print 'coke',num
@decorate2
@decorate1
def water(num):
print 'water',num
coke(10) # little 10 coke 11
water(11) # hot 11 little 12 water 13
- water(11) = decorate2(decorate1(water))(11)
- decorate2(decorate1(water))(11) = decorate2(f1)(11),此时func1 = water
- decorate2(f1)(11) = f2(11),此时func2 = f1;
- 执行f2(11),在执行f1(11),在执行water(11)
装饰类方法
在Python里方法和函数几乎一样.唯一的区别就是方法的第一个参数是一个当前对象的(self
)
也就是说你可以用同样的方式来装饰方法!只要记得把self
加进去:
def method_friendly_decorator(method_to_decorate):
def wrapper(self, lie):
lie = lie - 3
return method_to_decorate(self, lie)
return wrapper
class Lucy(object):
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
self.age = <span class="hljs-number">32</span>
<span class="hljs-decorator">@method_friendly_decorator</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sayYourAge</span><span class="hljs-params">(self, lie)</span>:</span>
<span class="hljs-keyword">print</span> <span class="hljs-string">"I am %s, what did you think?"</span> % (self.age + lie)
l = Lucy()
l.sayYourAge(-3)
#输出: I am 26, what did you think?
补充:
def decorate2(func2):
def f2():
print('进入decorate2...')
func2()
print('离开decorate2...')
return f2
def decorate1(func1):
def f1():
print('进入decorate1...')
func1()
print('离开decorate1...')
return f1
@decorate2
@decorate1
def water():
print('进入water...')
print('离开water...')
@decorate1
def coke():
print('进入coke...')
print('离开coke...')
water()
'''
进入decorate2...
进入decorate1...
进入water...
离开water...
离开decorate1...
离开decorate2...
'''
print('#############################')
coke()
'''
进入decorate1...
进入coke...
离开coke...
离开decorate1...
'''