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
>>>

转载于:https://www.cnblogs.com/paomaliuju/p/5073273.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值