美文网首页
装饰器分析

装饰器分析

作者: 梦醒家先生 | 来源:发表于2018-07-06 11:24 被阅读0次

    1.闭包的引入

    格式写法:两个函数的嵌套,外层函数返回内层函数的引用,外层必须有参数
    作用:在执行函数的时候可以把我们的外层函数参数保存在内存中

    def 外层函数(参数):
        def 内层函数():
            print('内层执行', 参数)
    
        return 内层函数
    
    
    内层函数的引用 = 外层函数('-----')
    内层函数的引用()
    
    # 执行结果
    内层执行 -----
    

    2.闭包和函数的区分

    • 如果没有闭包,我们需要每次创建直线函数的函数的传参。这样,我们就需要更多的参数传递,也减少了代码的可移植性。
    def sum(money1, money2):
        """计算收入"""
        print(money1 + money2)
    
    sum(100,200)
    sum(1000, 2000)
    
    • 闭包:在执行函数的时候可以把我们的外层函数参数保存在内存中
    def set_reat(reat):
        def sum1(money1, money2):
            print((money1 + money2) * reat)
    
        return sum1
    
    
    # 作用:在执行函数的时候可以把我们的外层函数参数保存在内存中
    reat_68 = set_reat(0.68)
    reat_68(1000, 2000)
    reat_68(1000, 30000)
    
    sum = set_reat(0.68)
    sum(1000, 2000)
    

    注意点
    由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

    3.闭包修改外部函数的参数(变量)

    # python3使用方法
    def set_fun(args):
        def test():
            nonlocal args
            args += 100
            print('test', args)
        return test
    
    
    test = set_fun(100)
    test()
    
    # 执行结果
    >>200
    

    4.装饰器的演变使用

    需求:在不改变原有的函数,添加额外的功能
    写代码要遵循开放封闭原则

    • 封闭:已实现的功能代码块
    • 开放:对扩展开发
    # 2.定义一个闭包
    def set_func(func):  # func = test
        def call_func():
            print('权限设置')
            func()
    
        return call_func
    
    
    # 1.先定义一个函数
    # 3.装饰器
    @set_func  # set_func===> test = set_func(test)
    def test():
        print('test')
    
    test()
    
    #执行结果
    >>权限认证
    >>test
    
    一个装饰器一个函数内存图.png

    结论:
    1.装饰前的test,是由func指向的
    2.装饰后的test,其实是call_func

    5.万能装饰器

    def set_func(func):
        def call_func(*args, **kwargs):
            print('添加功能')
            return func(*args, **kwargs)
    
        return call_func
    
    # 语法糖
    @set_func
    def test(*args, **kwargs):
        print(args)
        print(kwargs)
        return 100
    
    
    print(test('123', a=111))
    # 执行结果
    >>添加功能
    >>('123',)
    >>{'a': 111}
    >>100
    
    
    多个装饰器装饰一个函数的内存图.png

    结论:
    1.装饰前,test指向func
    2.装饰后,test执行call_func
    3.道德上我的装饰器是不会更改原先的函数值,及调用的方式(可以更改装饰器里调用的函数)
    4.传参数的时候,func,装饰前 test,func,call_set三者的参数必须一样

    相关文章

      网友评论

          本文标题:装饰器分析

          本文链接:https://www.haomeiwen.com/subject/jidvuftx.html