一、装饰器的执行
装饰器本质就是函数,功能是为其他函数添加附加功能。
实现原则:
不修改被修饰函数的源代码。
不修改被修饰函数的调用方法。
def auth(func):
import functools
@functools.wraps(func) # 把被装饰函数的信息放入到闭包中
def inner(*args,**kwargs):
# 传入函数执行前可以写入代码
ret = func(*args,**kwargs) # 闭包,执行 index()
# 传入函数执行后可以写入代码
return ret
return inner
'''
@auth = auth(index) 把被装饰函数传入到装饰器函数中
'''
@auth
def index():
print('index')
print(index.__name__)
# 加装饰器输出:inner;不加装饰器输出:index
# @functools.wraps(func) 输出:index
from functools import wraps
def decorator_name(f):
@wraps(f)
def decorated(*args, **kwargs):
if not can_run:
return “Function will not run”
return f(*args, **kwargs)
return decorated
二、多个装饰器的执行顺序
如果装饰器的功能需要先执行,应该放在离要执行函数最近的位置,否则会无法执行装饰器的功能,具体情况根据装饰器的功能而定。
三、装饰器执行过程
3.1、不带参数的装饰器
@auth
def index():
print('index')
'''
在执行时先把 index 函数传入到 auth 装饰器函数中,并在装饰器函数的闭包中运行 index(),并返回函数。
'''
带参数的装饰器
@auth(‘参数’)
def index():
print('index')
'''
1、去掉@,运行auth(‘参数’),返回装饰器中的函数;
2、再执行时把 index 函数传入装饰器函数中,在装饰器函数的闭包中运行 index(),并返回。
'''
四、装饰器实现过程
#装饰器:对类或者函数进行功能的扩展
'''
#第一步:基本函数
def la():
print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天')
#调用函数
la()
la()
#第二步:扩展函数功能(不能修改原函数)
#用于扩展基本函数的函数
def kuozhan(func):
#扩展功能1
print('la前参拜祈求')
#调用基本函数
func()
#扩展功能2
print('la后还愿感谢')
#基本函数
def la():
print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天')
#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
la = kuozhan(la)
print(la)
#调用函数
#la()
#la()
#第三步:使用语法糖(就是语法) @语法
#用于扩展基本函数的函数
def kuozhan(func):
#扩展功能1
print('la前参拜祈求')
#调用基本函数
func()
#扩展功能2
print('la后还愿感谢')
#基本函数
@kuozhan #la = kuozhan(la)#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
def la():
print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天')
print(la)
#调用函数
#la()
#la()
#第四步:基本装饰器的实现
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的la函数)
def newla():
#扩展功能1
print('la前参拜祈求')
#调用基本函数
func()
#扩展功能2
print('la后还愿感谢')
#添加返回值
return newla
#基本函数
@kuozhan #la = kuozhan(la)#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
def la():
print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天')
#print(la)
#调用函数
la()
la()
#第五步:带有参数的装饰器和带有返回值的装饰器
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的la函数)
def newla(shui,na):
#扩展功能1
print('la前参拜祈求')
#调用基本函数
func(shui,na)
#扩展功能2
print('la后还愿感谢')
#添加返回值
return newla
#基本函数
@kuozhan #la = kuozhan(la)#扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
def la(who,where):
print(who,'在',where,'tuokuzi')
print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天')
#print(la)
#调用函数
la('yangjun','羊圈')
la('yanfei','鸟巢')
#带有返回值的函数
#用于扩展基本函数的函数
def kuozhan(func):
#内部函数(扩展之后的la函数)
def newla():
#扩展功能1
print('la前参拜祈求')
#调用基本函数
result = func()
#扩展功能2
print('la后还愿感谢&