如果看完这篇文章,你还是弄不明白装饰器;,今天小编就来说说关于python常用的装饰器?下面更多详细答案一起来看看吧!
python常用的装饰器
主要内容:- 小目标:理解装饰器
- 主要内容:装饰器基本语法,装饰器应用
如果看完这篇文章,你还是弄不明白装饰器;
你来找我,我保证不打你,我给你发100的大红包。
1. 一个案例1.1 需求:两个函数mySum:计算列表的和,参数必须为列表
myMax:统计列表的最大值,参数必须为列表
代码实现:
def mySum(args):
#判断args是否是列表
if isinstance(args, list):
return sum(args)
return -1
def myMax(args):
#判断args是否是列表
if isinstance(args, list):
return max(args)
return -1
print(mySum([1,2,3]))
print(mySum((1,2,3)))
print(myMax(123))
结果:6, -1, -1
1.2 新需求:参数可以使元组修改代码:
def mySum(args):
#判断args是否是列表
if isinstance(args, (list, tuple)):
return sum(args)
return -1
def myMax(args):
#判断args是否是列表
if isinstance(args, (list, tuple)):
return max(args)
return -1
print(mySum([1,2,3]))
print(mySum((1,2,3)))
print(myMax(123))
结果:6,6,-1
1.3 问题:- 如果增加其他数据结构如何处理?
- 如果有N个这样函数如何处理?
从上一步修改中可以看到,判断条件相同,唯一不同时处理方式。
2. 闭包的应用对上面进行分析,解决方式:
每个函数的核心功能不同,但是判断条件相同
将相同部分拆分成函数,
闭包使用:
def decoFunc(func):
#checkArgs为内置函数,func对于checkArgs是外部变量
def checkArgs(args):
#统一处理参数
if isinstance(args, (list, tuple)):
return func(args)
return -1
return checkArgs
#自定义的sun函数
mySum = decoFunc(sum)
#自定义max函数
myMax = decoFunc(max)
print(mySum([1,2,3]))
print(mySum((1,2,3)))
print(myMax(123))
结果:6,6,-1
分析:
1.decoFunc(func)中的func对于checkArgs为外部变量
2.decoFunc返回值为checkArgs函数
3.mySum, myMax指向checkArgs函数,但是每个函数内部的func不同
4.mySum, myMax调用之后,检查args,然后使用不同func处理ars
大家可以把这个过程理解下,然后我们来看装饰器;
3.装饰器如何理装饰器:
1.装饰器:修改函数并返回新的函数;
2.装饰器与闭包原理类似,但是只用来处理函数;
基本语法:
@deco
def func(args):
pass
来看例子
def decoFunc(func):
#checkArgs为内置函数,func对于checkArgs是外部变量
def checkArgs(args):
#统一处理参数
if isinstance(args, (list, tuple)):
return func(args)
return -1
print('checkArgs:', checkArgs)
return checkArgs
@decoFunc
def mySum(args):
return sum(args)
print('mySum:', mySum)
结果:
checkArgs: <function decoFunc.<locals>.checkArgs at 0x000001C4A21580D8>
mySum: <function decoFunc.<locals>.checkArgs at 0x000001C4A21580D8>
分析:
- mySum变量名指向decoFunc中的返回值:checkArgs函数
- @decoFunc就是装饰器的语法糖
- 从结果中看到,我们没有调用mySum函数,但是装饰器函数会默认执行
装饰器实质:对比两个例子,mySum = decoFunc(mySum)
3.带参数的装饰器新需求:在不修改checkArgs参数前提下,调用mySum,myMax前打印相应的函数名
直接上代码:
def decoFunc(fname):
print("call decoFunc")
#在_decoFunc在加一层函数,返回_decoFunc
def _decoFunc(func):
#checkArgs为内置函数,func对于checkArgs是外部变量
def checkArgs(args):
#统一处理参数
if isinstance(args, (list, tuple)):
print("call func:", fname)
return func(args)
return -1
print('checkArgs:', checkArgs)
return checkArgs
return _decoFunc
@decoFunc('mySum')
def mySum(args):
return sum(args)
print('mySum:', mySum)
mySum([1,2,3,4,5])
结果:
call decoFunc
checkArgs: <function decoFunc.<locals>._decoFunc.<locals>.checkArgs at 0x000001C4A1D00B88>
mySum: <function decoFunc.<locals>._decoFunc.<locals>.checkArgs at 0x000001C4A1D00B88>
call func: mySum
分析:<函数包含关系:decoFunc->_decoFunc->checkArgs
@decoFunc('mySum')执行过程:
1.执行decoFunc('mySum'),设置fname,返回_decoFunc
2.执行@decoFunc('mySum')实质是@返回_decoFunc,
3.mysum = _decoFunc(mySum)
大家看到装饰器,尤其带参数的装饰器,感觉晕晕的, 我们要做的,就是一步一步分析,搞清楚原理; 以上就是装饰相关内容;
总结:- 理解装饰器,必须先理解闭包;
- 理解闭包,必须弄清楚作用域及函数返回值;
- 装饰器在实际工作,尤其适用第三方框架时候(Djano,Scrapy等),应用十分广泛