day4-装饰器
装饰器:
定义:本质是函数,为其他函数添加附加功能
原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方法
实现装饰器知识储备
1.函数即变量
2.高阶函数
a.把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b.返回值中包含函数名(不修改函数的调用方式)
1 import time 2 3 # 定义一个bar函数 4 def bar(): 5 time.sleep(3) 6 print('in the bar') 7 8 # 参数为函数名,返回值包含函数名 9 def test2(func): 10 print(func) 11 return func 12 13 # 把bar函数名当参数传给test2, 此时返回的是bar函数的地址 14 bar = test2(bar) 15 # 调用bar函数 16 bar()
3.嵌套函数
一个函数的函数体内,用def 去声明一个函数,而不是去调用其他函数,称为嵌套函数。
1 def timmer(func): 2 def wrapper(*args,**kwargs): 3 start_time = time.time 4 func(*args,**kwargs) 5 stop_time = time.time() 6 print('the func run time is %s' % (stop_time-start_time)) 7 return warpper
高阶函数+嵌套函数 =》 装饰器
我们把上面的组合下:
1 @timer =>(等于) test1=timer(test1) 2 def test1(): 3 time.sleep(3) 4 print('in the test1') 5 6 def test2(name): 7 print name 8 9 test1() 10 test2()
复杂用法:装饰器带参数
1 import time 2 user,passwd = 'alex','abc123' 3 def auth(auth_type): 4 print("auth func:",auth_type) 5 def outer_wrapper(func): 6 def wrapper(*args, **kwargs): 7 print("wrapper func args:", *args, **kwargs) 8 if auth_type == "local": 9 username = input("Username:").strip() 10 password = input("Password:").strip() 11 if user == username and passwd == password: 12 print("\033[32;1mUser has passed authentication\033[0m") 13 res = func(*args, **kwargs) # from home 14 print("---after authenticaion ") 15 return res 16 else: 17 exit("\033[31;1mInvalid username or password\033[0m") 18 elif auth_type == "ldap": 19 print("搞毛线ldap,不会。。。。") 20 return wrapper 21 return outer_wrapper 22 def index(): 23 print("welcome to index page") 24 25 @auth(auth_type="local") # home = wrapper() 26 def home(): 27 print("welcome to home page") 28 return "from home" 29 @auth(auth_type="ldap") 30 def bbs(): 31 print("welcome to bbs page") 32 index() 33 print(home()) #wrapper() 34 bbs()
补充知识点(函数即变量、回收机制):


Python内存机制 : 比如赋值x=1,python会在内存中画个小房子,然后把1存进去,门牌号挂为x; 如果是函数,则把函数体存到内存里,以函数名为门牌号
Python回收机制:没有门牌号=》没有引用的时候
匿名函数: 没有门牌号,立马被回收
calc = lambda x: x*3
print(calc(3))
如果没有使用del方法删除,则一直被占用,直到程序结束,del方法删除的事门牌号,Python定期检查,若没有发现门牌号,则回收

浙公网安备 33010602011771号