一、什么是装饰器
1、对现有已经实现功能的代码进行扩展。
2、不用修改被撞时对象的源代码和调用方法
二、装饰器的使用
无参数装饰器:
示例:
def zsq(func):
def yz(args):
print("验证")
return func(args)
return yz
@zsq
def hs(name):
print("我是一个函数%s"%name)
return "hs fanhuizhi"
ceshi = hs("wz")
print(ceshi)
执行过程:
1、将zsq加载到内存中。
2、碰到@zsq,会执行zsq函数将@zaq下的函数当作参数传入zsq中(相当于zsq(hs))。
3、此时func形参等于hs函数,读取yz函数到内存,return yz函数的内存地址到hs函数(@zsq就相当于(hs = zsq(hs)))。
4、此时执行ceshi = hs(“wz”),由于hs被return 回来的yz函数覆盖,这里执行的就相当于ceshi = yz(“wz”)。
5、执行yz函数,首先print(“验证”),然后return func(args),这句return func(args)的意思是执行func函数并把函数的返回值返回给调用yz函数的对象,而调用yz函数的为ceshi = hs(“wz”),所以这一步就是把返回值传给hs(“wz”)并赋值给ceshi变量。
6、在这里执行func(args)由于第三步的时候func等于hs函数所以就相当于执行hs函数。
有参数装饰器:
示例:
def hs1(canshu1, canshu2):
print("第一个函数")
def hs2(canshu1, canshu2):
print("第二个函数")
def zsq(hs_1, hs_2):
def home(home_func):
def panduan(pd1, pd2):
hs1_return = hs_1(pd1, pd2)
if (hs1_return != None):
return hs1_return
home_return = home_func(pd1, pd2)
if (home_return != None):
return home_return
hs2_return = hs_2(pd1, pd2)
if (hs2_return != None):
return hs2_return
return panduan
return home
@zsq(hs1, hs2)
def index(canshu1, canshu2):
print("index")
index(‘w‘,‘z‘)
#执行过程
1、解释器从上往下解释python代码首先将hs1函数加载到内存,然后把hs2和zsq函数也加在到内存。
2、碰到@zsq(hs1, hs2),解释器首先会执行zsq(hs1, hs2),把hs1和hs2当作参数传给zsq赋值给zsq的形参hs_1和hs_2(这里相当于@zsq = zsq(hs1,hs2))。
3、将home函数加载到内存并return给@zsq。
4、执行装饰器将index函数当作值传给zsq函数,由于@zsq已被home函数覆盖这时候相当于执行index = home(index)。
5、读取panduan函数到内存中并把panduan函数的内存地址返回给调用home函数的index中。
6、执行index(‘w’,’z’),由于index被panduan覆盖这里就相当于执行panduan(‘w’,’z’)。
7、执行panduan函数中的代码(不再赘述…)
三、装饰器语法:
被装饰函数的正上方,单独一行
@deco1
@deco2
@deco3
def foo():
pass
foo=deco1(deco2(deco3(foo)))
四、装饰器补充:wraps
from functools import wraps
def deco(func):
@wraps(func) #加在最内层函数正上方
def wrapper(*args,**kwargs):
return func(*args,**kwargs)
return wrapper
@deco
def index():
‘‘‘哈哈哈哈‘‘‘
print(‘from index‘)
print(index.__doc__)
原文地址:https://www.cnblogs.com/qingmu6/p/8918975.html