装饰器

一. 装饰器

定义:假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(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)

 

原文地址:https://www.cnblogs.com/shanghongyun/p/9925697.html