python成长之路11——装饰器
一. 什么是装饰器
装饰器模式:允许向一个现有的对象添加新的功能,同时又不改变其结构,满足了编程的开放封闭原则,是一种被大家广泛使用的代码设计模式。
二. python中的装饰器
1 def outer(func): 2 #func为要添加新功能的对象 3 def inner(*args,**kwargs): 4 #如果func有参数的话,inner要传入参数 5 print("在执行func前执行新添加的功能") 6 #新添加的功能 7 ret=func(*args,**kwargs) 8 print("在执行func后执行新添加的功能") 9 return ret 10 # 新添加的功能 11 return inner 12 #给函数应用装饰器:使函数f1()在执行前后都增加了新功能 13 @outer 14 def f1(): 15 print("f1") 16 f1()
三. 装饰器执行过程
在描述装饰器的执行过程之前,先对@+函数做个说明:
@+函数名 <==> 函数名()
有两个功能:1. 自动执行outer函数并且将其下面的函数名f1当作参数传递给outer
2. 将outer的返回值inner重新赋值给f1,f1就相当于“原f1+新添加功能”,这样就在不改变原f1结构的基础上给f1新添加了功能
详细过程:
1. 将outer函数加载入内存
2. 执行@outer 将函数名f1传给func(func=原f1),执行outer
3. 将inner函数加载入内存
4. 将outer函数的返回值inner,重新赋值给f1,(f1=inner)
5. 当调用f1时,就执行inner(),inner中的func=原f1
四. 装饰器适用场景
主要是权限控制。
1 USER_DIC={"alex":1,"wang":0,"jack":1} 2 #1代表已登录,0代表未登录 3 4 def check_login(func): 5 def inner(u): 6 if USER_DIC[u] == 1: 7 return func(u) 8 else: 9 print("[%s]未登录!" % u) 10 return inner 11 @check_login 12 def user(u): 13 print("欢迎[%s]使用xxx用户系统." % u) 14 15 user("alex") 16 user("wang") 17 18 执行结果: 19 欢迎[alex]使用xxx用户系统. 20 [wang]未登录!
五. 双层装饰器
1 USER_INFO={} 2 def login(): 3 inp=input("username>>>>") 4 USER_INFO["is_login"]=True 5 if inp == "admin": 6 USER_INFO["is_admin"]=True 7 8 def check_login(func): 9 def inner(*args,**kwargs): 10 if USER_INFO.get("is_login",None): 11 ret = func(*args,**kwargs) 12 return ret 13 else: 14 print("must login") 15 return inner 16 def check_admin(func): 17 def inner(*args,**kwargs): 18 if USER_INFO.get("is_admin",None): 19 ret = func(*args,**kwargs) 20 return ret 21 else: 22 print("must admin") 23 return inner 24 @check_login 25 def index(): 26 print("index") 27 28 @check_admin 29 @check_login 30 def home(): 31 print("home") 32 33 def main(): 34 while True: 35 inp = input("1:login; 2:index; 3:home\t>>>") 36 if inp == "1": 37 login() 38 elif inp == "2": 39 index() 40 elif inp == "3": 41 home() 42 else: 43 print("error") 44 main() 45 46 执行结果: 47 1:login; 2:index; 3:home >>>2 48 must login 49 1:login; 2:index; 3:home >>>1 50 username>>>>qq 51 1:login; 2:index; 3:home >>>2 52 index 53 1:login; 2:index; 3:home >>>3 54 must admin 55 1:login; 2:index; 3:home >>>1 56 username>>>>admin 57 1:login; 2:index; 3:home >>>3 58 home
注意:装饰器是从下往上渲染的。