• 简述装饰器


    作者:Dayle,转载请说明出处:https://www.cnblogs.com/dayle/p/10003844.html
     
    装饰器:就是一个函数:
    定义:装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器,使得其满足:
    1:不能修改源代码
    2:不能修改调用方式
    高阶函数:a:把一个函数名当作实参传给另一个函数
    b:返回值中包含函数名
    嵌套函数:一个函数中嵌套另一个函数
     
    简单装饰器代码

     

    以下,用行数代替每一行的内容,
    首先,从上往下看,函数只有被调用的时候才会执行,所以执行的第一步就是语法糖@deco,他就在test函数的上方,那么,我们就可以得出实际上他的另一种写法就是 test = deco(test)(规定,不需要理解,就得这么记)
     
    然后我们假设在执行这条命令: test = deco(test)。
    相当于把test当作deco的实参传给了deco函数,那么我们看deco函数:第二行
     
    deco函数是一个嵌套函数,那么我们一步步往下看,
    第三行:里面还有一个函数,这个函数是wrapper函数,在形参的位置写了*args, **kwargs,这个代表传给函数的实参,那么就是‘aaa’,作用:为了防止工作中不止传入一个实参,而是很多个的时候,不需要在多次输入,直接调用所有实参。
    第四行:我之前说过,一看到@deco,就是看到了test = deco(test),那么可以得出,deco函数里的形参的值就是test。而deco函数的形参为func,那么,间接的func=test,那么,这里的func(*args, **kwargs)这个语句也就是可以按我们的理解转换成为test('aaa'),那么这个语句就是在执行test函数,那么现在,就要找到test函数来执行:第9行。
     
    第9行:执行test函数的结果就是:my name is aaa .
    执行完之后回到原位置继续执行
    第5行,打印‘添加新功能’
    那么wrapper函数就执行完成了。跳出这一层函数,再来看他的外面一层函数体:deco函数,他有一个返回值,返回值为wrapper,那这个值其实就是wrapper函数的内存地址
     
    然后看我注释的一行第12行。
    我说过这其实就是@deco的原型。
    那么这里将deco函数的返回值赋给了test,那么现在test已经不再是test了,而是wrapper,那么说,也就是wrapper函数的内存地址。test = wrapper
     
    第13行,test('aaa'),其实就是在执行 wrapper('aaa')
    那么结果如下:
     
    原理:
    现在返回头看我的装饰器的定义:
    那么现在我的函数体没有改变,我调用函数的方式也没有改变,但是结果却是添加新功能后的结果。这就满足了线上的环境。
     
    为什么要用嵌套函数:
    大家可以尝试一下,去掉一层函数,那么将无法实现将test函数重新定义为wrapper函数的功能。那么执行结果除了添加新功能的结果,还会在执行一次主test函数。故,需要嵌套函数。
     
    为什么要用返回值,为了重新给test定义,将wrapper赋值给test。
     
     
  • 相关阅读:
    CAS实战の简介
    高效程序员的45个习惯の排除万难奋勇前进
    高效程序员的45个习惯の对事不对人
    高效程序员的45个习惯の欲速则不达
    高效程序员的45个习惯の正确做事
    Java中Runnable和Thread的区别
    Intellij IDEA 14的注册机(Java版)
    session token防表单重提
    maven下@override标签失效
    Oracle sql 优化の索引监控
  • 原文地址:https://www.cnblogs.com/dayle/p/10003844.html
Copyright © 2020-2023  润新知