首页 > 其他分享 >decorator的用法及原理_F_hawk189_新浪博客

decorator的用法及原理_F_hawk189_新浪博客

时间:2022-11-16 12:07:04浏览次数:47  
标签:f1 name hawk189 def 用法 print decorator test decorator1


06

0、 概念

什么叫装饰器,其实也可以叫做包装器。即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来。

python中的装饰器分为两类:函数装饰器和类装饰器。

这里我们先讨论函数装饰器。

1. 不带参数的decorator

(1) 基本用法:



  1. def decorator1(func):  
  2.     def dec(*args):  
  3.         print 'pre action'  
  4.         result = func(*args)  
  5.         print 'post action'  
  6.         return result  
  7.     return dec  
  8.  
  9. @decorator1  
  10. def test_f1(name):  
  11.     print name  
  12.     return None  
  13.   
  14. test_f1('name1') #out: preaction/name1/post action  
  15. test_f1('name2') #out: preaction/name2/post action  



(2) 这种现象的内部原理:

在python内部,当你做了这件事情:



  1. @decorator1  
  2. def test_f1(name):  



其实就是 test_f1 = decorator1(test_f1) #即test_f1作为参数传递给func。

此后的test_f1是装饰器中的dec函数对象了,而不是原来的函数的名称。当调用test_f1(‘name1’)的时候,其实调用的是dec(‘name1’)函数,而在dec函数内部,又调用了func,这样就造成了装饰器的效果。

这也解释了func是被装饰函数,*arg是被装饰函数的参数—这种现象了。


2. 带参数的decorator

(1) 基本用法:



  1. def wap(name):  
  2.     def decorator1(func):  
  3.         def dec(*args):  
  4.             print name  
  5.             print 'pre action'  
  6.             result = func(*args)  
  7.             print 'post action'  
  8.             return result  
  9.         return dec  
  10.     return decorator1  
  11.  
  12. @wap('f1')  
  13. def test_f1(name):  
  14.     print name  
  15.     return None  
  16.  
  17. @wap('f2')  
  18. def test_f2(name):  
  19.     print name  
  20.     return None  
  21.   
  22. test_f1('name1') #out: f1/pre action/name1/post action  
  23. test_f1('name2') #out: f2/pre action/name2/post action  



带参数的decorator,作用是通过传递参数可以定制不同的装饰器。


(2) 内部原理

这里和上面 不带参数的decorator类似,



  1. @wap('f1')  
  2. def test_f1(name):  



内部逻辑为: test_f1 = wap(‘f1’)(test_f1)

这里wap(‘f1’)返回是decorator1函数对象,这样的话,wap(‘f1’)(test_f1)其实就是decorator1(test_f1),这样就和上面的一样了。只不过这里传递了一个参数’f1’进入decorator内部,使得我们可以操作这个参数。


3. 函数decorator也可以修饰类成员函数



  1. class FOO:  
  2.     @decorator1  
  3.     def fun(self):  
  4.         print self.name  



注意此时fun的self会被传递到decorator1中。此时把self看做普通的函数入参。


4. 函数decorator的叠加

(1) 用法



  1. def decorator1(func):  
  2.     def dec(*args):  
  3.         print 'd1 pre'  
  4.         result = func(*args)  
  5.         print 'd1 post'  
  6.         return result  
  7.     return dec  
  8.   
  9. def decorator2(func):  
  10.     def dec(*args):  
  11.         print 'd2 pre'  
  12.         result = func(*args)  
  13.         print 'd2 post'  
  14.         return result  
  15.     return dec  
  16.  
  17. @decorator1  
  18. @decorator2  
  19. def test(name):  
  20.     print name  
  21.   
  22. test('test') #out: d1 pre/d2 pre/test/d1 post/d2 post  



(2) 原理



  1. @decorator1  
  2. @decorator2  
  3. def test(name):  
  4.     print name  



和上面的类似,内部原理是:

test = decorator1(decorator2(test))

注意decorator1(decorator2(test)),不是说先执行decorator2(test),再执行decorator1。

而是先把decorator2(test)作为参数,最先执行decorator1,然后再执行decorator2.。

标签:f1,name,hawk189,def,用法,print,decorator,test,decorator1
From: https://blog.51cto.com/u_15858333/5855688

相关文章

  • python爬取智联招聘信息_F_hawk189_新浪博客
    分享今天写的一个爬取智联招聘信息的爬虫,使用了requests和re模块,没有写注释,但是代码都比较简单,不是太难,这是爬取的信息:​​​​​​以下是源码部分:复制过来又没......
  • python中同时迭代对个iterable对象_F_hawk189_新浪博客
    题外话:最近因为课程需要开始深入了解Python语言。因为以前一直用的Java、C++等强类型的静态语言,现在突然使用Python确实感受到了很大的不同。直观感觉就是,在Python中总是......
  • QT客户端与Java服务端进行https通信_F_hawk189_新浪博客
    网上也有一部分教程,不过我还是踩了许多的坑,所以整理了一下网上看到的和自己的一些收获。首先:,Tomcat.truststore(包含信任库),首先说明一下这个两个文件   cl......
  • virtviewerUsbredirUSB重定向_F_hawk189_新浪博客
    编译virtviewer之前执行的configure命令,是没有使能usb-redir相关的功能,virtviewer是否支持usbredir是完全依赖于spice-gtk的。virtviewer对spice-gtk的依赖关系,可以从vi......
  • Vue的data,components,methods,computed,mounted,activated,deactivated,beforeCreate
    1、dataVue会递归将data的属性转换为getter/setter,从而让data的属性能够响应数据变化。对象必须是纯粹的对象(含有零个或多个的key/value对)data(){ return......
  • CSharp: Decorator Pattern in donet 6
     ///<summary>///装饰模式DecoratorPattern亦称:装饰者模式、装饰器模式、Wrapper、Decorator///</summary>publicinterfaceIDataSource......
  • python 中 filter函数的用法
     和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。 ......
  • python 中内建函数map的用法
     map函数会根据提供的函数对指定序列做映射。通过定义可以看到,这个函数的第一个参数是一个函数,剩下的参数是一个或多个序列,返回值是一个集合。map的作用是以参数序列中......
  • spring@Validated校验用法
    1、controller添加注解publicBaseResponseaddOrUpdateUnit(@RequestBody@ValidatedRiskUnitDtoriskUnitDto){doublePreventDataService.addOrUpdateUnit(......
  • Python三目运算符(三元运算符)用法详解
    我们从一个具体的例子切入本节内容。假设现在有两个数字,我们希望获得其中较大的一个,那么可以使用ifelse语句,例如:ifa>b:max=aelse:max=b但是 Pytho......