zoukankan      html  css  js  c++  java
  • Python

    一、装饰器

      本身就是函数,都是用def语法来定义的,为其他函数添加附加功能。

    二、应用场景

      假设目前编写的函数已经上线运行了,某一天,产品有个需求,要在这个里面新增一个功能,那怎么去做这个事?最简单的就是:重新编码。但是问题是程序已经运行了,修改程序源码,会有风险发生。

      所以说,我要新增一个功能,不能够修改函数的源代码,且不改变原函数的调用方式,这个时候装饰器就出现了

    闭包

      要了解装饰器首先要知道什么是闭包

      总结起来就是:

        1、外层函数返回了内存函数的引用

        2、内层函数引用了外层函数的参数

    1  def out(num):  #外层函数
    2 print('1')
    3 def inner(): #内层函数
    4 print(num)
    5 print('5')
    6 print('2')
    7 return inner #返回了内层函数的引用
    8
    9 res = out(4)
    10 res()

      这就是闭包,那么闭包是怎么执行的呢

    1
    2
    4
    5

     当调用out() 的时候,此时执行外层函数,输出1,输出2 ,注意:当程序执行到第3行时,只是在此声明了一个函数,并没有做任何事情,此时res接收了out的返回值(inner函数的引用)

     当调用res() 的时候,此时相当于调用inner函数,输出4,输出5,执行完毕

       

     执行内部函数的时候,外层函数的变量并没有被销毁,可以一直被调用。

    def out(num):
        print('1')
        def inner(num_inner):
            print(num)
            print(num_inner)
        print('2')
        return inner
    
    res = out(4)
    res(11)
    res(22)
    res(33)
    res(44)

       此时输出结果为

    1
    2
    4
    11
    4
    22
    4
    33
    4
    44

      此种应用,虽然编写函数的时候会稍微麻烦点,但是可以反复调用,不会被释放,传参数的时候也可以简化

      

    装饰器

      1、只是在原来的函数基础上增加新的函数,达到在执行原来的函数之前或者之后执行新添加的功能

      2、不改变原函数的调用方式,原来调用哪个函数现在还调用哪个函数

    示例一:

    def out1(func):    #此函数相当于拓展函数
        print('外层开始执行')
        def inner1():
            print('内层开始执行')
            func()
        print('外层执行完毕')
        return inner1
    
    @out1
    def ma():       #此函数相当于原来的函数 print('这是一个主函数') ma()           #调用方式依旧是原来的调用

    输出结果

    外层开始执行
    外层执行完毕
    内层开始执行
    这是一个主函数

    示例二:

    def out1(canshu):
        print('外层开始执行')
        def inner1():
            print('内层开始执行')
            canshu()
        print('外层执行完毕')
        return inner1
    
    # @out1
    def ma():
        print('这是一个主函数')
    ma = out1(ma)
    ma()

    输出结果

    外层开始执行
    外层执行完毕
    内层开始执行
    这是一个主函数

    可以看到上面两种方式实现了同样的功能(示例一属于闭包函数装饰了原来的函数)

    可以看出 

    ma = out1(ma)
    ma()

    只是被 语法糖 @out1 替换掉了

    在函数ma上面加上了@out1,就相当于 out1(ma)

    当程序执行到@定义的位置,就会自动执行闭包体的外层函数,当执行到原函数调用时,会自动执行闭包体的内层函数

    下面附上详细图片

       

  • 相关阅读:
    shader之渐变长方体实现(threejs)
    shader之threejs应用
    shader之cesium应用
    pip install -- Failed building wheel for XXX
    pycharm -- 界面乱码
    Android Studio -- 优化速度
    django -- ImageField 上传图片修改头像
    AI -- 回溯法解决四皇后问题
    Android Studio -- 真机测试
    傻瓜函数式编程
  • 原文地址:https://www.cnblogs.com/yidada/p/10573141.html
Copyright © 2011-2022 走看看