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