装饰器
普通装饰器:用于查看函数运行时间
def use_time(fun): def inner(*args,**kwargs): start_time = time.time() result = fun() stop_time = time.time() print("任务执行使用时间%s秒" % (stop_time-start_time)) return result return inner @use_time def fun(): for i in range(1000000): pass return "success"
复杂装饰器:装饰器带参数
import time user,passwd = 'aaa','123' def auth(auth_type): print("auth func:",auth_type) def outer_wrapper(func): def wrapper(*args, **kwargs): print("wrapper func args:", *args, **kwargs) if auth_type == "local": username = input("Username:").strip() password = input("Password:").strip() if user == username and passwd == password: print("\033[32;1mUser has passed authentication\033[0m") res = func(*args, **kwargs) # from home print("---after authenticaion ") return res else: exit("\033[31;1mInvalid username or password\033[0m") elif auth_type == "ldap": print("搞毛线ldap,不会。。。。") return wrapper return outer_wrapper def index(): print("welcome to index page") @auth(auth_type="local") # home = wrapper() def home(): print("welcome to home page") return "from home" @auth(auth_type="ldap") def bbs(): print("welcome to bbs page") index() print(home()) #wrapper() bbs()
从表面上来看,函数的代码和盗用方法都没有改变。但是实际上,你在调用被装饰函数fun()时,在装饰器中已经改变了函数的名字,此时调用的是装饰器中的内层函数inner()。
因此,为了不改变被装饰函数的名称,我们用@functools.wraps()来防止函数的名称被改变。
from functools import wraps def log(func): @wraps(func) # 防止函数的名字被改变 def inner(*args, **kwargs): print('call %s()' % tete.__name__) return func(*args, **kwargs) return inner @log def tete(x,y): print(x+y)