十九、装饰器

mac2024-10-02  25

1、装饰器的作用及开放封闭原则

1、装饰器的作用:在不修改函数的调用方法,但是还想在原来的函数前后添加功能 2、开放封闭原则的具体含义:对扩展开放、对修改封闭

2、装饰器的一般语法:

首先,先看一个实例:计算某个函数的运行时间

import time def timer(f): #step one def inner(): #step four start = time.time() #step six time.sleep(0.01) #step seven ret = f() #step eight end = time.time() #step nine print(end - start) #step ten return ret #step eleven return inner f = timer(f) #得到的结果是inner ret = f() #相当于调用inner函数,即inner()

该实例还可优化,python中有一种叫语法糖的东西,可以简化代码,简化之后的代码如下:

import time def timer(f): #step one @wraps(f) #语法糖,指明该装饰器修饰的是f,即timer的形参 def inner(): #step four start = time.time() #step six time.sleep(0.01) #step seven ret = f() #step eight end = time.time() #step nine print(end - start) #step ten return ret #step eleven return inner @timer #这个等价于:f = timer(f) def f(): return "HelloWorld!" ret = f() #这里直接调用即可,而不需要上面“f = timer(f)”这一步

上面将的都是单个装饰器修改一个函数,下面的这个实例将的是多个装饰器修饰一个函数时其执行顺序。

def wrapper1(func):#本例中func=inner2 #step one def inner1(*args,**kwargs): #step seven print('wrapper1,before func')#step eleven ret = func() #step twelve 此时func = inner2,故此相当于ret = inner2() print('wrapper1,after,func') #step seventeen return ret #step nineteen inner1()执行完毕,返回结果 return inner1 #step eight def wrapper2(func):#本例中func = f #step two def inner2(*args,**kwargs):#step four print('wrapper2,before,func')#step thirteen ret = func(*args,**kwargs) #step fourteen 此时,func = f,故此相当于ret = f() print('wrapper2,after,func') #step fifteen return ret #step sixteen inner2()执行完毕,返回结果 return inner2#step five @wrapper1#f = wrapper1(f)=inner1 #step six wrapper(f)中f=inner2;f = inner1 @wrapper2#f = wrapper2(f)=inner2 #step three f = inner2 def f(): #step nine print('函数本体正在执行') f()#inner1 #step ten 相当于:inner1()

其结果为:

wrapper1,before func wrapper2,before,func 函数本体正在执行 wrapper2,after,func wrapper1,after,func

从中可以得出当多个装饰器修饰一个函数时,其执行顺序是:先执行上面装饰器(@wrapper1)的前面的语句,在执行下面装饰器(@wrapper2)前面的语句,然后执行被修饰的函数(f),最后依次执行下面的和上面的函数之后的语句。 总结: 一般装饰器的固定格式如下:

def 装饰器名(被装饰的函数):#装饰器英文名'wrapper' def 函数名(*args,**kwargs):#定义一个新的内部函数,用来执行被装饰的函数 此处编写被装饰函数被执行前需要执行的代码 结果 = 被装饰的函数() 此处编写被装饰函数被执行之后需要执行的代码 return 结果 return 函数名 @装饰器名 def 被装饰函数(参数): 函数体
最新回复(0)