1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:sking
4 #Python3 装饰器
5
6 #装饰器本质就是函数(功能就是装饰其他函数也就是为其它函数添加附加功能)
7 #装饰器的原则:
8 #1. 不能修改被装饰的函数的源代码(比如正在线上云线的app,你不能直接修改它的源代码,因为这样可能会造成很多不好的连锁反应)
9 #2. 不能修改被装饰的函数的调用方式
10 #以上两个原则可以总结为:装饰器对它装饰的函数是完全透明的,就是装饰器不影响被装饰的函数,被装饰的函数想怎么运行还怎么运行。
11
12 # #实现装饰器的知识储备:
13 # #1.函数即“变量”
14 # #2.高阶函数:满足下列条件之一就称为高阶函数
15 # #a:把一个函数名当做实参传给另外一个函数(可以实现在不修改被装饰函数代码的情况下,为其添加其它功能)
16 # import time
17 # import string
18 #
19 # def bar():
20 # time.sleep(1)
21 # print('in the bar')
22 #
23 # def test(func):
24 # start_time = time.time()
25 # func() #实际就是运行bar函数 将打印 in the bar
26 # end_time = time.time()
27 # print("func run time is :%s" % (end_time-start_time))
28 # print(func) #将打印<function bar at 0x002F0810> 内存地址也就是门牌号bar
29 #
30 # test(bar)
31 # #b:返回值中包含函数名(可以实现在不修改被装饰函数的调用方式)
32 # #import time
33 # def bar():
34 # time.sleep(1)
35 # print('in the bar')
36 #
37 # def test2(func):
38 # start_time = time.time()
39 # func() #实际就是运行bar函数 将打印 in the bar
40 # end_time = time.time()
41 # print("func run time is :%s" % (end_time-start_time))
42 # return func #将返回<function bar at 0x002F0810> 内存地址也就是门牌号bar
43 #
44 # print(test2(bar))#将打印<function bar at 0x002F0810> 内存地址也就是门牌号bar
45 # t = test2(bar)
46 # t() # 就相当于运行bar函数 打印in the bar
47 # #如果
48 # bar = test2(bar)
49 # #重新给bar引用 因为test2(bar)返回的是bar函数的内存地址,
50 # # 所有这里等于bar又重新引用到了原来的地址,
51 # # 所以
52 # bar() #还是相当于运行bar函数 打印in the bar
53 #
54 # #实现装饰器的知识储备:
55 # #3.嵌套函数(在一个函数体内用def再声明一个函数)
56 # def foo():
57 # print("in the foo")
58 # def bbr():
59 # print("in the bbr")
60 #
61 # bbr() #调用bbr函数
62 # foo() #调用foo函数
63 # """
64 # 运行结果:
65 # in the foo
66 # in the bbr
67 # """
68 #
69 # #高阶函数 + 嵌套函数 -->> 装饰器(decorator) 又叫语法糖
70 # print('真正的装饰器来了'.center(50, '-'))
71 #
72 # def timer(func):
73 # def deco():
74 # start_time = time.time()
75 # func() #这里其实运行的是 bar()函数
76 # end_time = time.time()
77 # print(f'func run time is{end_time-start_time}')
78 # return deco
79 #
80 # @timer #就相当于bar = timer(bar)
81 # def bar():
82 # time.sleep(1)
83 # print("in the bar")
84 #
85 # bar() #这里其实运行的是deco()函数
86 #
87 # #被装饰的函数带参数
88 # def timer2(func2):
89 # def deco2(*args, **kwargs): #加上*args **args就可以接受任意的位置参数或关键字参数了
90 # start_time = time.time()
91 # func2(*args, **kwargs) #这里其实运行的是 bar2()函数
92 # end_time = time.time()
93 # print(f'func2 run time is{end_time-start_time}')
94 # return deco2
95 #
96 # @timer2 #就相当于bar2 = timer(bar2)
97 # def bar2(*args, **kwargs):
98 # time.sleep(1)
99 # print("in the bar2", args, kwargs)
100 #
101 # bar2("haha") #这里其实运行的是deco()函数
102 # bar2("haha", name="youyou") #('haha',) {'name': 'youyou'}
103
104 #特殊结构的装饰器,被装饰的函数有返回值
105 #要求浏览网页的时候有些页面需要登录后才能看到内容
106 #
107 # user, pwd = 'aaa', '123'
108 # def auth(func):
109 # def wapper(*args, **kwargs):
110 # username = input("Username:").strip()
111 # password = input("Password:").strip()
112 #
113 # if user == username and pwd == password:
114 # print(f'\033[32:1mWelcome {username} !\033[0m')
115 # return func(*args, **kwargs) #将func的返回内容(也就是home()的返回内容) 返回给调用函数wapper(也就是返回给下面的调用home())
116 # #当然如果这里后面还有内容,可以先把func()的返回内容赋值给一个变量res = func(*args, **kwargs)
117 # #这样最后再执行return res
118 # else:
119 # exit(f'\033[31:1mError!\033[0m')
120 # return wapper
121 #
122 #
123 # def index():
124 # print("welcome to index page")
125 #
126 # @auth
127 # def home():
128 # print("welcome to home page")
129 # return "return from home"
130 #
131 # @auth
132 # def bbs():
133 # print("welcome to bbs page")
134 #
135 # index()
136 # print(home())
137 # """
138 # 结果:
139 # Welcome aaa !
140 # welcome to home page
141 # return from home
142 # """
143
144 #特殊结构的装饰器,被装饰的函数有返回值,装饰器有参数
145 #要求浏览网页的时候有些页面需要登录后才能看到内容,但是用户名的认证有些是本地认证,有些是远程认证
146
147 user, pwd = 'aaa', '123'
148 def auth(auth_type): #这里传递的是auth_type
149 def out_wapper(func): #这里传递的是func
150 def wapper(*args, **kwargs):
151 if auth_type == 'local':
152
153 username = input("Username:").strip()
154 password = input("Password:").strip()
155
156 if user == username and pwd == password:
157 print(f'\033[32:1mWelcome {username} !\033[0m')
158 return func(*args, **kwargs) # 将func的返回内容(也就是home()的返回内容) 返回给调用函数wapper(也就是返回给下面的调用home())
159 # 当然如果这里后面还有内容,可以先把func()的返回内容赋值给一个变量res = func(*args, **kwargs)
160 # 这样最后再执行return res
161 else:
162 exit(f'\033[31:1mError!\033[0m')
163 elif auth_type == 'ldap':
164 print('bbs 输出ldap方式')
165 else:
166 print('Worng!')
167
168 return wapper
169 return out_wapper
170
171 def index():
172 print("welcome to index page")
173
174 @auth(auth_type='local') #这里就相当于 auth(auth_type='local') 这里就相当于运行了函数auth() 所以接下来还要运行 out_wapper(func)(也就是相当于home = out_waper(home))
175 def home():
176 print("welcome to home page")
177 return "return from home"
178
179 @auth(auth_type='ldap')
180 def bbs():
181 print("welcome to bbs page")
182
183 index()
184 print(home())
185 bbs()
186 """
187 结果:
188 Welcome aaa !
189 welcome to home page
190 return from home
191 bbs 输出ldap方式
192 """