B站视频链接
目录
装饰器
import time
time.sleep(10) #让程序在执行到这个位置的时候停一会儿(10s
time.time() #获取当前时间:从1970.1.1到现在过了多少秒
1.Eg.计算函数运行时间
原始代码
```python
def func():
start=time.time()
print('这段代码跑完了')
time.sleep(0.01) #让程序执行到这个位置的时候停一会(因为程序执行时间太少)
end=time.time()
print(end-start)
func()
```
修改v1
```python
#0.
import time
#1.计时器
def timmer(f):
start=time.time()
f() #调用func(),以参数的形式传进来
end=time.time()
print(end-start)
#2.自定义的函数
def func():
time.sleep(0.01)
print('这段代码跑完了')
#3.实际调用
timmer(func)
```
修改v2(+基本装饰器的使用)
- 【装饰器的作用】不修改函数的调用方式 func(), 还在原来的函数前后添加功能【使用闭包函数
- timmer()就是一个装饰器函数,只是对一个函数 有一些装饰作用
#0.
import time
#1.自定义的函数
def func(): #1.
time.sleep(0.01) #10.
print('这段代码跑完了') #11.
#2.计时器
def timmer(f): #装饰器函数 #2. #3.2 f>>>func()刚刚传来的内存地址
def inner(): #4.定义inner()
start = time.time() #8.
f() #被装饰的函数 #9.f()实际调用func()(以参数的形式传进来)
end = time.time() #12.
print(end-start) #13.finnal
return inner #5.返回inner给3.1的func 【inner作为timmer()的返回值==func
#3.实际调用
func = timmer(func) #3.1调用timmer(),将1.的func()的内存地址传给timmer() #6.
func() #7.实际执行的是inner()
修改v3(+语法糖:装饰器简便使用)
- 语法糖:在被装饰的函数上加@装饰器的名字==(3.实际调用中注释的那句话
#0.
import time
#1.计时器
def timmer(f): #装饰器函数
def inner():
start = time.time()
f() #被装饰的函数
end = time.time()
print(end-start)
return inner
#2.自定义的函数
@timmer #语法糖 #执行3.实际调用
def func():
time.sleep(0.01)
print('这段代码跑完了')
#func = timmer(func) #3.实际调用:替换为 @timmer
func()
修改v4(+函数有返回值)
- 函数执行后才执行它的返回
- 返回值返回给调用它的地方
#0.
import time
#1.计时器
def timmer(f): #1.定义
def inner(): #4.执行,定义
start = time.time() #8.
res = f() #*** #9.调用func(); #func()的返回值'aaa'>>>res
end = time.time() #13.
print(end-start) #14.
return res #*** 15.返回被装饰函数f()的执行结果;res作为inner()的返回值,inner()==res=='aaa'
return inner #5.timmer()==inner
#2.自定义的函数
@timmer #3.执行timmer()
def func(): #2.定义
time.sleep(0.01) #10.
print('这段代码跑完了') #11.
return 'aaa' #*** #12.'aaa'==func()
#func=timmer(func) #(3) #6.inner>>>func
res = func() #7.实际调用的是inner()//原始inner()无返回值;需获取inner的返回值
print(res) #16.res=='aaa'
>>>
这段代码跑完了
0.013279199600219727
aaa
修改v5(+传一个参数)
#0.
import time
#1.计时器
def timmer(f): #1.定义
def inner(a): #4.执行,定义
start = time.time() #8.
res = f(a) #*** #9.调用func(); #func()的返回值'aaa'>>>res
end = time.time() #13.
print(end-start) #14.
return res #*** 15.返回被装饰函数f()的执行结果;res作为inner()的返回值,inner()==res=='aaa'
return inner #5.timmer()==inner
#2.自定义的函数
@timmer #3.执行timmer()
def func(a): #2.定义
time.sleep(0.01) #10.
print('这段代码跑完了',a) #11.
return 'aaa' #*** #12.'aaa'==func()
#func=timmer(func) #(3) #6.inner>>>func
res = func(1) #7.实际调用的是inner()//原始inner()无返回值;需获取inner的返回值
print(res) #16.res=='aaa'
>>>
这段代码跑完了 1
0.01414799690246582
aaa
修改v6(+万能动态参数,任意传参)
#0.
import time
#1.计时器
def timmer(f):
def inner(*args,**kwargs): #(1,2)/(1)
start = time.time()
res = f(*args,**kwargs) #f(1,2)
end = time.time()
print(end-start)
return res
return inner
#2.自定义的函数1
@timmer
def func(a,b):
time.sleep(0.01)
print('这段代码跑完了',a,b)
return 'aaa'
#2.自定义的函数2
@timmer
def func1(a):
time.sleep(0.01)
print('这段代码跑完了',a)
return 'aaa'
#func=timmer(func)
res = func(1,2)
res = func(1,b=2)
print(res)
2.装饰器定式
def wrapper(f): #装饰器函数,f是被装饰函数
def inner(*args,**kwargs): #定义内部函数,名字和wrapper的返回值一致
''' 在被装饰函数之前要做的事'''
res = f(*args,**kwargs) #内部函数参数要原封不动传给被装饰函数
''' 在被装饰函数之后要做的事'''
return res #返回被装饰函数
return inner #将内部函数返回给装饰器函数
@wrapper
def func(a,b):
time.sleep(0.01)
print('这段代码跑完了',a,b)
return 'aaa'
res = func(1,2)
print(res)
3.装饰器进阶
- EG:调用被装饰函数实际调用的是装饰函数中的内部函数
def wrapper(func): #func = holiday
def inner(*args,**kwargs):
print('在被装饰函数之前要做的事')
res = func(*args,**kwargs)
print('在被装饰函数之后要做的事')
return res
return inner
@wrapper
def holiday(day):
print('全天放假%s天'%day)
return '好开心'
res = holiday(3) #inner()
print(holiday.__name__) #.__name__ 查看函数所属地址的函数名
#holiday的内存地址指向inner,因此打印的是inner的名字
>>>
在被装饰函数之前要做的事
全天放假3天
在被装饰函数之后要做的事
inner ***
3.1 functools.wraps
- 运用这个方法,可以在外部调用函数的时候,调用的是原函数
from functools import wraps #***
def wrapper(func): #func = holiday
@wraps(func) #***给inner函数装饰
def inner(*args,**kwargs):
print('在被装饰函数之前要做的事')
res = func(*args,**kwargs)
print('在被装饰函数之后要做的事')
return res
return inner
@wrapper
def holiday(day):
print('全天放假%s天'%day)
return '好开心'
res = holiday(3) #inner()
print(holiday.__name__) #.__name__ 查看函数所属地址的函数名
>>>
在被装饰函数之前要做的事
全天放假3天
在被装饰函数之后要做的事
holiday ***
3.2 带参数的装饰器
import time
FLAGE = True
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag == True:
start = time.time()
res = func(*args,**kwargs)
end = time.time()
print(end-start)
return res
else:
res = func(*args,**kwargs)
return res
return inner
return timmer
#timmer = timmer_out(FLAGE) 省略了这一步
@timmer_out(FLAGE) #两步:先调timmer_out(),返回值timmer>>>timmer_out(flag); @timmer== wahaha=timmer(wahaha)
def wahaha():
time.sleep(0.1)
print('wahahhahhahah')
@timmer_out(FLAGE)
def erguotou():
time.sleep(0.1)
print('toutoutoutouto')
wahaha()
erguotou()
3.3 多个装饰器装饰同一个函数
双层装饰器
def wrapper1(func):
def inner1():
print('wrapper1, before func')
func()
print('wrapper1, after func')
return inner1
def wrapper2(func):
def inner2():
print('wrapper2, before func')
func()
print('wrapper2, after func')
return inner2
@wrapper2
@wrapper1
def f():
print('in f')
f()
>>>
wrapper2, before func
wrapper1, before func
in f
wrapper1, after func
wrapper2, after func
三层装饰器+返回值
def wrapper1(func):
def inner1():
print('wrapper1, before func')
ret = func()
print('wrapper1, after func')
return ret
return inner1
def wrapper2(func):
def inner2():
print('wrapper2, before func')
ret = func()
print('wrapper2, after func')
return ret
return inner2
def wrapper3(func):
def inner3():
print('wrapper3, before func')
ret = func()
print('wrapper3, after func')
return ret
return inner3
@wrapper3
@wrapper2
@wrapper1
def f():
print('in f')
return '哈哈哈'
print(f())
>>>
wrapper3, before func
wrapper2, before func
wrapper1, before func
in f
wrapper1, after func
wrapper2, after func
wrapper3, after func
哈哈哈
开发原则:开放封闭原则
- 开放:对扩展是开放的
- 封闭:对修改是封闭的(不能修改封板的代码)
网友评论