python笔记24_装饰器

主要内容:

  • 小目标:理解装饰器
  • 主要内容:装饰器基本语法,装饰器应用

若是看完这篇文章,你仍是弄不明白装饰器;
你来找我,我保证不打你,我给你发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, -1ide

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,-1code

1.3 问题:

  • 若是增长其余数据结构如何处理?
  • 若是有N个这样函数如何处理?

从上一步修改中能够看到,判断条件时相同的,惟一不一样时处理方式。作用域

2. 闭包的应用

对上面进行分析,解决方式:get

每一个函数的核心功能不一样,可是判断条件相同
将相同部分拆分红函数,使用闭包处理下:it

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,-1io

  • 分析:

    decoFunc(func)中的func对于checkArgs为外部变量
    decoFunc返回值为checkArgs函数
    mySum, myMax指向checkArgs函数,可是每一个函数内部的func不一样
    mySum, myMax调用以后,检查args,而后使用不一样func处理ars
    你们能够吧这个过程理解下,而后咱们来看装饰器

3.装饰器

如何理装饰器:

装饰器:修改函数并返回新的函数;
装饰器与闭包原理相似,可是只用来处理函数;

基本语法:

@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函数br/>@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,返回_decoFuncbr/>2.执行@decoFunc('mySum')实质是@返回_decoFunc,
3>mysum = _decoFunc(mySum)

你们看到装饰器,尤为带参数的装饰器,感受晕晕的,
咱们要作的,就是一步一步分析,搞清楚原理;
以上就是装饰相关内容;

总结:

  • 理解装饰器,必须先理解闭包;
  • 理解闭包,必须弄清楚做用域及函数返回值;
  • 装饰器在实际工做,尤为适用第三方框架时候(Djano,Scrapy等),应用十分普遍
相关文章
相关标签/搜索