python装饰器
装饰器
概念:可以在不修改原来代码的情况下(函数原有的功能或者类原有的功能),为需要被装饰的函数或者类增加新的功能或者添加限制调剂以及帮助输出
常用种类
- 函数的装饰器
- 类的装饰器
- 不管是哪种 类型的装饰器设计模式原则是:开放封闭的原则(对外扩展开发,对内关闭修改)
1.1 装饰器的定义
装饰器的必要构成条件
- 装饰器本身是一个函数
- 装饰器的返回值一定是一个函数的引用(函数的名字)
- 装饰器只能必须一定是只有一个形参
- 形参是用来接收函数的引用(需要被装饰的函数的名字)
装饰器本质上是一个闭包函数
1 #装饰器实现登录 2 def check(func): # func=shopping 3 def inner(): 4 print("开始进入登录页面") 5 print("扫码登录") 6 print("登录成功") 7 func() #func=shopping func()=shopping() 8 return inner 9 10 11 #原有的购物功能 12 def shopping(): 13 print("商品加入购物车") 14 print("付款") 15 16 17 #原始使用方式:调用装饰器,传递需要被装饰的函数作为实参 18 shopping1=check(shopping) # 2---3(inner函数不会被执行,但是加载到内存)--8--18 19 #check(shopping)返回结果:shopping1=inner 20 shopping1() #shopping1()=innner() 3-4-5-6-7--12--13--14
1.2 装饰器的语法糖使用
python提供了装饰器的精简的书写格式:语法糖格式
使用@符号加装饰器的名字即可:@check
注意:装饰器语法糖一定要写在被调用函数的上面
1 #装饰器实现登录 2 def check(func): # func=shopping 3 def inner(): 4 print("开始进入登录页面") 5 print("扫码登录") 6 print("登录成功") 7 func() #func=shopping func()=shopping() 8 return inner 9 10 11 #原有的购物功能 12 @check #说明:shopping=check(shopping)----shopping=inner 13 def shopping(): 14 print("商品加入购物车") 15 print("付款") 16 17 #shopping()=inner() 18 shopping() 19 20 #被装饰的函数赋值给了func形参 21 #func=shopping 22 #装饰器被调用完返回结果是inner 23 #shopping=inner 24 #shopping()=inner()
语法糖@装饰器名 执行方式
- 在整个模块开始运行代码的时候,会优先执行装饰器代码,装饰器不需要手动调用,自动执行
- 装饰器的本质就是一个闭包函数,只不过传递过去的实参是被装饰的函数的引用(函数的名字)
1.3 装饰器的使用场景
- 统计一个函数的执行时间
- 输出日志信息
- 缓存处理
- 实现路由
1 import time 2 3 #统计一个函数的执行时间 4 5 def get_time(func): 6 def inner(): 7 begin=time.time() 8 func() 9 end=time.time() 10 print(f"被装饰的函数执行的时间为{end-begin}") 11 12 return inner 13 14 @get_time 15 def func1(): 16 for i in range(1,1000000): 17 print(i) 18 19 func1()
1.4 带有参数的装饰器
1 #用带有参数的装饰器完成计数器的加减乘除功能 2 def mark(flag):#flag用来接收装饰器的实参 3 def out_func(fn): #用来接收被装饰器的函数引用 4 def inner_func(num1,num2): #需要被装饰的函数的实参 5 if flag=="+": 6 print(f"您输入的装饰器实参是{flag},正在努力进行加法运算中") 7 result=fn(num1,num2) 8 elif flag=="-": 9 print(f"您输入的装饰器实参是{flag},正在努力进行减法运算中") 10 result=fn(num1,num2) 11 else: 12 result="您输入的运算符号不在范围内" 13 return result 14 15 return inner_func 16 return out_func 17 18 # 带有参数的装饰器代码执行流程: 19 #2---->16---->3-->15--->4--->5(8)--->6(9)(11)---7(10)(12)---(13) 20 21 #装饰器语法糖的调用过程 22 #mark=mark("+")----mark=out_func 23 # @mark("+") 24 # def add(a,b): 25 # result=a+b 26 # return result 27 #------------------------------------- 28 # @out_func 29 # def add(a,b): 30 # result=a+b 31 # return result 32 #add=out_func(add)=inner_func 33 #add=inner_func() 34 @mark("+") 35 def add(a,b): 36 result=a+b 37 return result 38 39 @mark("-") 40 def sub(a,b): 41 result=a - b 42 return result 43 44 #add=inner_func() 45 print(add(22,56)) 46 print(sub(15,6))