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
双层装饰器

注意:装饰器是从下往上渲染的。

posted @ 2017-02-27 15:14  meitangyanyan  阅读(195)  评论(0编辑  收藏  举报