Python3 装饰器

  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 """

 

posted @ 2019-01-28 22:15  SKING_Python  阅读(294)  评论(0编辑  收藏  举报