装饰器
转载请标明出处(http://blog.csdn.net/lis_12/article/details/52693521)
github demo
装饰器可以用来引入日志;
增加计时检测性能;
给函数增加事务能力,在不改动原函数的情况下,增加该函数额外的功能
语法
-
装饰器就是把其他函数作为参数的函数;
-
装饰器以@开头,紧接着是装饰器的名字,然后是是被修饰的函数和装饰函数的可选参数,格式如下
@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):
def __init__(self):
self.age = 32
@method_friendly_decorator
def sayYourAge(self, lie):
print "I am %s, what did you think?" % (self.age + lie)
l = Lucy()
l.sayYourAge(-3)
#输出: I am 26, what did you think?