python装饰器
简介
python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
简单的装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import time def count_time(func): def wrapper(): t1 = time.time() func() print("执行时间为:", time.time() - t1) return wrapper @count_time def baiyu(): print("我是攻城狮白玉") time.sleep(2) if __name__ == '__main__': baiyu()
|
装饰器传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import time def count_time(func): def wrapper(*args, **kwargs): t1 = time.time() func(*args, **kwargs) print("执行时间为:", time.time() - t1) return wrapper @count_time def blog(name): print('进入blog函数') name() print('我的博客') if __name__ == '__main__': blog(baiyu)
|
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 27 28 29
| import time
def deco(func): def wrapper(*args, **kwargs): startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper
@deco def func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b))
@deco def func2(a,b,c): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b+c))
if __name__ == '__main__': f = func func2(3,4,5) f(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 27 28 29 30 31 32
| import time def count_time_args(msg=None): def count_time(func): def wrapper(*args, **kwargs): t1 = time.time() func(*args, **kwargs) print(f"[{msg}]执行时间为:", time.time() - t1) return wrapper return count_time @count_time_args(msg="baiyu") def fun_one(): time.sleep(1) @count_time_args(msg="zhh") def fun_two(): time.sleep(1) @count_time_args(msg="mylove") def fun_three(): time.sleep(1) if __name__ == '__main__': fun_one() fun_two() fun_three()
|
类装饰器
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import time
class BaiyuDecorator: def __init__(self, func): self.func = func print("执行类的__init__方法")
def __call__(self, *args, **kwargs): print('进入__call__函数') t1 = time.time() self.func(*args, **kwargs) print("执行时间为:", time.time() - t1)
@BaiyuDecorator def baiyu(): print("进入baiyu函数") time.sleep(2)
def python_blog_list(): time.sleep(5) print('1111')
@BaiyuDecorator def blog(name): print('进入blog函数') name() print('2222')
if __name__ == '__main__': baiyu() print('--------------') blog(python_blog_list)
|
带参数的类装饰器
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 27 28 29 30 31 32 33 34 35 36 37
|
class BaiyuDecorator: def __init__(self, arg1, arg2): print('执行类Decorator的__init__()方法') self.arg1 = arg1 self.arg2 = arg2 def __call__(self, func): print('执行类Decorator的__call__()方法') def baiyu_warp(*args): print('执行wrap()') print('装饰器参数:', self.arg1, self.arg2) print('执行' + func.__name__ + '()') func(*args) print(func.__name__ + '()执行完毕') return baiyu_warp @BaiyuDecorator('Hello', 'Baiyu') def example(a1, a2, a3): print('传入example()的参数:', a1, a2, a3) if __name__ == '__main__': print('准备调用example()') example('Baiyu', 'Happy', 'Coder') print('测试代码执行完毕')
|
装饰器的顺序
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 27 28 29 30 31 32 33 34
| def dec1(func): print("1111") def one(): print("2222") func() print("3333") return one def dec2(func): print("aaaa") def two(): print("bbbb") func() print("cccc") return two @dec1 @dec2 def test(): print("test test") test()
''' 17~20行是装载装饰器的过程,相当于执行了test=dect1(dect2(test)),此时先执行dect2(test),结果是输出aaaa、将func指向函数test、并返回函数two,然后执行dect1(two),结果是输出1111、将func指向函数two、并返回函数one,然后进行赋值。 ''' ''' 用函数替代了函数名test。 22行则是实际调用被装载的函数,这时实际上执行的是函数one,运行到func()时执行函数two,再运行到func()时执行未修饰的函数test。 '''
|