python全栈-Day 11
一、装饰器的初成
1、一个需要做装饰器的示例
import time
def func():
time.sleep(0.1) #让程序暂停执行0.1s
print('你好')
def timer(f): #运行f函数,并计算f函数的执行时间----这样做要修改全部的函数名称为timer,非常消耗时间
start = time.time() #1533213779.934297,从1970到现在经过的秒数----获取当前的时间戳
f()
end = time.time()
print(end - start)
timer(func)
2、使用装饰器的方法解决以上问题,好处是:只要 func1 = timer(func1) 赋值不同函数,就可以实现计算多个函数的执行时间的功能
- 不需要修改函数的调用方式,但是可以在已有的函数前后添加一些公共功能
- timer就是一个装饰器函数,只是对一个函数,有装饰作用,被装饰的函数是f
import time
def func1():
time.sleep(0.1)
print('func1')
def timer(f):
def inner():
start = time.time()
f()
end = time.time()
print(end - start)
return inner
func1 = timer(func1) #实际上func1指向了inner的内存地址
func1() #执行inner函数
二、开放封闭原则
1、开放:对扩展是开放的
2、封闭:对修改是封闭的----如果修改了老的函数,可能影响之前已经使用该函数的功能,因此不允许修改
三、一个基础的装饰器的最终形成和固定格式
1、不完整的装饰器
不完整的装饰器:没有返回值
import time
def timer(f): #装饰器函数
def inner():
start = time.time()
f()
end = time.time()
print(end - start)
return inner
@timer #语法糖,@装饰器函数名。在被装饰函数上方紧贴着装饰器,相当于 func1 = timer(func1)
def func1():
time.sleep(0.1)
print('func1')
return '你好呀'
print(func1()) #func1相当于inner,因此返回值是inner的返回值None,拿不到func1本身的返回值
2、完整的装饰器
#完整的装饰器
import time
def timer(f): #装饰器函数
def inner():
start = time.time()
ret = f()
end = time.time()
print(end - start)
return ret
return inner
@timer #语法糖,@装饰器函数名。在被装饰函数上方紧贴着装饰器,相当于 func1 = timer(func1)
def func1():
time.sleep(0.1)
print('func1')
return '你好呀'
print(func1()) #func1相当于inner,因此返回值是inner的返回值None,拿不到func1本身的返回值
3、注意,如果被装饰函数有参数,则 被装饰函数、装饰器函数、装饰器函数中调用的被装饰函数、执行被装饰函数 4个位置都需要加上参数
4、如果被装饰函数有多个参数,则需要遵循 形参、实参的规则(注意灵活使用 *args、**kwargs)
#完整的装饰器----多个被装饰参数,携带多个位置参数和关键字参数
import time
def timer(f): #装饰器函数
def inner(*args,**kwargs): #*args、**kwargs作为形参,实现 多个元素-单个元组、字典 的操作
start = time.time()
ret = f(*args,**kwargs) #*args、**kwargs作为实参,实现 单个元组、字典-打散到单个元素的操作
end = time.time()
print(end - start)
return ret
return inner
@timer
def func1(a):
time.sleep(0.1)
print('func1',a)
return '你好呀'
@timer
def func2(a,b):
time.sleep(0.1)
print('func1',a,b)
return '你好呀'
print(func1('func1-a'))
print(func2('func2-a','func2-b'))
5、装饰器的固定格式
import time
def wrapper(f): #装饰器函数,f是被装饰的函数名----形参
def inner(*args,**kwargs):
'''在被装饰函数之前要做的事'''
ret = f(*args,**kwargs)
'''在被装饰函数之后要做的事'''
return ret
return inner
@wrapper #语法糖,@装饰器函数名,等同于 func = wrapper(func),func被赋值为inner
def func(a,b): #被装饰的函数
time.sleep(0.1)
print('func',a,b)
return 'func结束啦'
print(func('ddfs',22))

浙公网安备 33010602011771号