一. 装饰器
定义:假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
原则:基于开放封闭原则
封闭原则:对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
开放原则:对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
1.实现目标:登录功能和index功能
1 def login(): 2 user=input("请输入用户名:") 3 pwd=input("请输入密码:") 4 if user=="shy" and pwd=="123": 5 print("登录成功") 6 else: 7 print("用户名或密码错误") 8 def index(): 9 print("this is index")
2.只有登录才能调用index函数
1 def login(): 2 user=input("请输入用户名:") 3 pwd=input("请输入密码:") 4 if user=="shy" and pwd=="123": 5 index() 6 else: 7 print("用户名或密码错误") 8 def index(): 9 print("this is index") 10 login()
结果:只能调用index函数,不灵活
3.登录后能调用各种函数
1 def login(func): 2 user=input("请输入用户名:") 3 pwd=input("请输入密码:") 4 if user=="shy" and pwd=="123": 5 func() 6 else: 7 print("用户名或密码错误") 8 def index(): 9 print("this is index") 10 def foo(): 11 print("this is foo") 12 login(foo)
结果:不符合开放原则,导致所有调用index,或foo的地方都要更改
4.在保证index,foo开放的前提下,添加登录功能
1 def login(func): 2 def inner(): 3 user = input("请输入用户名:") 4 pwd = input("请输入密码:") 5 if user == "shy" and pwd == "123": 6 func() 7 else: 8 print("用户名或密码错误") 9 return inner 10 11 def index(): 12 print("this is index") 13 def foo(): 14 print("this is foo") 15 index=login(index) 16 index() 17 foo=login(foo) 18 foo()
结果:每一个只有登录才能调用的函数都要加上这句话index=login(index)
5.Django为其提供了快捷的方法,语法糖(装饰器)
1 def login(func): 2 def inner(): 3 user = input("请输入用户名:") 4 pwd = input("请输入密码:") 5 if user == "shy" and pwd == "123": 6 func() 7 else: 8 print("用户名或密码错误") 9 return inner 10 @login 11 def index(): 12 print("this is index") 13 @login 14 def foo(): 15 print("this is foo") 16 # index=login(index) #语法糖相当于这句话 17 index()
结果:在每个需要登录才能调用的方法上加@login
6.例:在每个函数执行后都打印执行该函数的所需时间
1 def timer(func): 2 import time 3 def inner(): 4 start=time.time() 5 func() 6 end=time.time() 7 cost=end-start 8 print(cost) 9 return inner 10 @timer 11 def add(): 12 s=0 13 for i in range (30000000): 14 s+=i 15 print(s) 16 add()
7.带参数的装饰器
1 def timer(func): 2 import time 3 def inner(x,y): 4 start=time.time() 5 func(x,y) 6 end=time.time() 7 cost=end-start 8 print(cost) 9 return inner 10 @timer 11 def add(x,y): 12 print(x+y) 13 add(50,54)
8.满足各个函数参数不等的装饰器
1 def timer(func): 2 import time 3 def inner(*args,**kwargs): 4 start=time.time() 5 func(*args,**kwargs) 6 end=time.time() 7 cost=end-start 8 print(cost) 9 return inner 10 @timer 11 def add(x,y): 12 print(x+y) 13 add(50,54) 14 @timer 15 def x(x,y,z): 16 print(x*y*z) 17 x(1,2,3)