• Python装饰器的理解


     1 def square_add(func):
     2     def new_function1(*args, **kwargs):
     3         result = func(*args, **kwargs)
     4         return result ** 2
     5     return new_function1
     6 
     7 def document_it(func):
     8     def new_function2(*args, **kwargs):
     9         print('Running function: ', func.__name__)
    10         print('Positional arguments: ', args)
    11         print('Keyword arguments: ', kwargs)
    12         result = func(*args, **kwargs)
    13         print('Result: ', result)
    14         return result
    15     return new_function2
    16 
    17 #一个函数可以拥有多个装饰器,且从距离该函数def最近的装饰器开始,依次向上执行
    18 
    19 @square_add
    20 @document_it
    21 def add_ints(a, b):
    22     return a + b

    add_ints函数本身是计算给定的两个int类型参数的和,但是,在此函数定义之前有“@装饰器名字”的表达式,意味着,该函数被其他函数装饰。所以,add_ints函数的调用结果就不只是求和了。一个函数可以拥有多个装饰器,且从距离该函数def最近的装饰器开始,依次向上执行。装饰器document_it距离被装饰的函数add_ints最近,因此,优先执行该装饰器。当add_ints函数被调用时,即本例中“add_ints(3,5)”,实际执行的过程如下:


    1.调用函数document_it(add_ints),我们发现document_it本身是返回了new_function2,调用端用一个名叫add_ints的函数来接收这个new_function2的返回值;

    注意:add_ints已经不是那个只求和的函数了

    2.add_ints函数实际上现在指向的是new_function2,因为new_function2这个函数(是document_it的内部函数)可以有任意多个位置参数或关键字参数,所以,我们可以通过“add_ints(3,5)”这样的方式,来给new_function2传入一组位置参数(以元组的形式将3、5传入);

    3.执行new_function2的函数体,很明显,print('Running function: ', func.__name__),这条语句中func是指add_ints;args位置参数是一个元祖(3,5);kwargs关键字参数没有传入参数,所以是空字典;接下来是这条语句“result = func(*args, **kwargs)”,我们已经知道func实际是指add_ints,那么func(*args, **kwargs)就相当于add_ints(3,5),因此,result的值就是add_ints(3,5)的返回值,即8;紧接着print打印result的值:8;最后返回result的值8;到这一步,document_it这个装饰器已经执行完毕,接下来就是执行下一个装饰器square_add。

    4.执行square_add(func),此时,func是指?由上面的分析,我们可知,被document_it装饰后的add_ints函数,实际上是指new_function2,所以,在执行square_add(func)时,func就是指的new_function2。为了证明这一点,我们可以在square_add这个函数中加一句print(func):


    5.由第4步可知,程序实际上是执行square_add(new_function2),而square_add函数是返回new_function1函数,同样用名字叫做add_ints的变量来接收这个函数,也就是说,此时add_ints实际上是指向new_function1:



    6.执行add_ints(3,5)就相当于new_function1(3,5),即执行的是new_function1的函数体,此时new_function1的参数是位置参数元组(3,5)。由于此时的func是指new_function2,所以,result = func(*args, **kwargs)就相当于将new_function2(3,5)的返回值赋值给result,我们已经明白new_function2(3,5)恰好是装饰器document_it的返回值8,因此,result = 8;接下来,返回8的平方,即64.


    综上所述,最终的执行结果是:
    >>> add_ints(3, 5)
    Running function:  add_ints
    Positional arguments:  (3, 5)
    Keyword arguments:  {}
    Result:  8
    64
    >>>

  • 相关阅读:
    网站优化网站前端优firedebug详情(转)
    网站优化HTTP REQUEST与web service 性能测试比较
    网站优化谈百度、Google搜索引擎最近的变化(转网文)
    网站优化QQ用户粘性
    网站优化广州SEM大会小节
    网站优化前端设计在不同浏览器上面的兼容
    网站优化网站前端优化好帮手
    谈谈我对CSS层叠的理解
    获取浏览器的可视区域尺寸
    【转载】关于setTimeout,理解JavaScript定时机制
  • 原文地址:https://www.cnblogs.com/paomaliuju/p/5073273.html
Copyright © 2020-2023  润新知