目录
一.装饰器
1.什么是装饰器
python装饰器用于拓展原来函数功能的一种函数,这个函数的返回值也是一个函数。
2.不带参数的简单装饰器
import time
print(time.time()) # 获取当前时间
time.sleep(10) #让程序在执行到这个位置的时候停一会儿
def timmer(f): #装饰器函数
def inner():
start = time.time()
ret = f() #被装饰的函数
end = time.time()
print(end - start)
return ret
return inner
@timmer # @装饰器函数名 @等价于func = timmer(func)
def func(): #被装饰的函数
time.sleep(0.01)
print('老板好同事好大家好')
return '新年好'
ret = func() #实际执行inner()
print(ret)
3.装饰器的运行步骤
4.装饰器的主要的功能和装饰器的固定结构
1) 主要功能
- 在不改变函数调用方式的基础上在函数的前、后添加功能。
2) 固定结构
#被修饰函数带参数的装饰器
def wrapper(f): # 装饰器函数,f是被装饰的函数
def inner(*args,**kwargs):
'''在被装饰函数之前要做的事'''
ret = f(*args,**kwargs) # 被装饰的函数
'''在被装饰函数之后要做的事'''
return ret
return inner
@wrapper # 语法糖 @装饰器函数名
def func(a,b): # 被装饰的函数
time.sleep(1)
print('装饰器',a,b)
return 'decrator'
# wraps版
from functools import wraps
def deco(func):
@wraps(func) #加在最内层函数正上方
def wrapper(*args,**kwargs):
return func(*args,**kwargs)
return wrapper
4.带参数的装饰器
1)单个装饰器装饰一个函数
# 例1
from functools import wraps
def wrapper(func): # func = holiday
@wraps(func)
def inner(*args, **kwargs):
print('在被装饰的函数执行之前做的事')
ret = func(*args, **kwargs)
print('在被装饰的函数执行之后做的事')
return ret
return inner
@wrapper # holiday = wrapper(holiday)
def holiday(day):
'''这是一个放假通知'''
print('全体放假%s天' % day)
return '好开心'
print(holiday.__name__) # holiday
print(holiday.__doc__) # 这是一个放假通知
ret = holiday(3)
print(ret)
# 在被装饰的函数执行之前做的事
# 全体放假3天
# 在被装饰的函数执行之后做的事
# 好开心
# 例2
import time
FLAGE = False
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag:
start = time.time()
ret = func(*args,**kwargs)
end = time.time()
print(end-start)
return ret
else:
ret = func(*args, **kwargs)
return ret
return inner
return timmer
# timmer = timmer_out(FLAGE)
@timmer_out(FLAGE) #wahaha = timmer(wahaha)
def wahaha():
time.sleep(0.1)
print('wahahahahahaha')
accept = wahaha()
print(accept)
2)多个装饰器装饰一个函数
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
"""
下面这两个装饰器等效于 f=wrapper2(wrapper1(f))
@wrapper2修饰装饰器@wrapper1, @wrapper1修饰函数def f(),
将函数f()赋值给wrapper1()的形参,再将wrapper1(f())赋值给wrapper2()的形参。
"""
@wrapper2
@wrapper1
def f():
print('in f')
return '哈哈哈'
print(f())
# wrapper2 ,before func
# wrapper1 ,before func
# in f
# wrapper1 ,after func
# wrapper2 ,after func
# 哈哈哈
执行的时候由上而下