一、定义
装饰器本质是函数,装饰其他函数,就是为其它函数添加附加功能
二、装饰器原则
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
三、实现装饰器的必要知识
1.函数即是变量
1 # def foo(): 2 # print("in the foo") 3 # bar() #bar未定义 4 # foo() 5 6 7 # def bar(): 8 # print("int the bar") 9 # def foo(): 10 # print("in the foo") 11 # bar() 12 # foo() 13 14 15 # def foo(): 16 # print("in the foo") 17 # bar() 18 # def bar(): 19 # print("int the bar") 20 # foo()
1 def foo(): 2 print("in the foo") 3 bar() 4 foo() 5 def bar(): #在调用后定义不会执行 6 print("int the bar")
2.高阶函数(高阶函数的两种表达方式)
2.1把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
1 import time 2 3 def bar(): 4 time.sleep(3) 5 print("in the bar") 6 7 def test1(func): 8 start_time = time.time() 9 func() 10 stop_time = time.time() 11 print("the func run time is %s" %(stop_time-start_time)) 12 test1(bar)
2.2返回值中包含函数名
1 import time 2 def bar(): 3 time.sleep(3) 4 print("in the bar") 5 def test2(func): 6 print(func) 7 return func#返回为内存地址 8 9 #print(test2(bar)) 10 # t=test2(bar) 11 # t() #run bar 12 bar=test2(bar) 13 bar() #返回的内存地址加上()就可以执行
3.嵌套函数
1 x=0 2 def a(): 3 x=1 4 def b(): 5 x=2 6 def c(): 7 x=3 8 print(x) 9 c() 10 b() #此处如果不执行b(),那么函数相当于什么都没干,因为没有print 11 a()
四、装饰器=高阶函数+嵌套函数
1 import time 2 3 def timer(func): #timer(test) func=test 4 def deco(): 5 start_time = time.time() 6 func() #此处运行被装饰函数test 7 stop_time = time.time() 8 print("func run time is %s" %(stop_time-start_time)) 9 return deco #返回deco的内存地址 10 11 12 @timer #相当于timer=timer(test),装饰器永远放在被装饰的函数前 13 def test(): 14 time.sleep(3) 15 print("this is test") 16 17 test()
五、如果装饰器的函数中包含参数
1 import time 2 3 def timer(func): 4 def deco(*args,**kwargs): #*args,**kwargs代表参数不确定的意思 5 start_time=time.time() 6 func(*args,**kwargs) 7 stop_time=time.time() 8 print("in the run time is %s" %(stop_time-start_time)) 9 return deco 10 11 @timer # test2 = timer(test2) = deco test2(name) = deco(name) 12 def test2(age,name,job): 13 time.sleep(1) 14 print("test2:",age,name,job) 15 16 test2(23,"Irlo","seller")
六、装饰器的使用实例
假设为网页添加登陆验证
1 user,pasd = "Irlo","12345" 2 def auth(auth_type): 3 print("auth func is",auth_type) 4 def type(func): 5 def wrapper(): 6 if auth_type == "local": 7 username = input("username:").strip() #strip移除字符串首尾指定的字符(默认为空格) 8 password = input("password:").strip() 9 if user==username and pasd==password: 10 print("