自学Python之路-Python基础+模块+面向对象
自学Python之路-Python网络编程
自学Python之路-Python并发编程+数据库+前端
自学Python之路-django
自学Python4.4 - 装饰器的进阶
- 1. functools.wraps
- 2. 带参数的装饰器
- 3. 多个装饰器装饰同一个函数
1. functools.wraps
对于装饰器我们都知道它主要的功能是:在不改变被装饰的函数及被装饰的函数的执行方式下,给函数增加额外功能的函数,但是我们在查看一个函数的注释和函数名的时候,如果这个函数带有装饰器,那么我们看到是注释信息和函数名就是装饰器里面的信息,而不是原来函数的信息,那么如何解决,实例如下:
from functools import wraps def wrapper(func): #func = holiday @wraps(func) def inner(*args,**kwargs): print('在被装饰的函数执行之前做的事') ret = func(*args,**kwargs) print('在被装饰的函数执行之后做的事') return ret return inner @wrapper #holiday = wrapper(holiday) def holiday(day): '''这是一个放假通知''' print('全体放假%s天'%day) return '好开心' print(holiday.__name__) print(holiday.__doc__) ret = holiday(3) #inner print(ret)
2. 带参数的装饰器
假如你们公司有300个函数使用了同一个装饰器,现在那领导让你把这些装饰器全部取消掉,你该怎么做?
使用最笨的办法一个一个添加?这样的话需要添加多长时间?然后几天之后领导说再把那些装饰器加上吧,你什么思想?那这个时候就可以用到带有参数的装饰器:
import time FLAGE = False def timmer_out(flag): def timmer(func): def inner(*args,**kwargs): if flag: start = time.time() ret = func(*args,**kwargs) end = time.time() print(end-start) return ret else: ret = func(*args, **kwargs) return ret return inner return timmer # timmer = timmer_out(FLAGE) @timmer_out(FLAGE) #wahaha = timmer(wahaha) def wahaha(): time.sleep(0.1) print('wahahahahahaha') @timmer_out(FLAGE) def erguotou(): time.sleep(0.1) print('erguotoutoutou') wahaha() erguotou()
3. 多个装饰器装饰同一个函数
在实际生产中,有的时候可能会用到多个装饰器来装饰同一个函数,下面我们就来说一下多个装饰器在装饰同一个函数具体的过程,实例如下:
def wrapper1(func): def inner1(): print('wrapper1 ,before func') ret = func() print('wrapper1 ,after func') return ret return inner1 def wrapper2(func): def inner2(): print('wrapper2 ,before func') ret = func() print('wrapper2 ,after func') return ret return inner2 def wrapper3(func): def inner3(): print('wrapper3 ,before func') ret = func() print('wrapper3 ,after func') return ret return inner3 @wrapper3 @wrapper2 @wrapper1 def f(): print('in f') return '哈哈哈' print(f())