Python 如何理解又晕又好用的装饰器,,Python 装饰器


Python 装饰器这东西对初学者来说是个坑,很容易绕晕,笔者当时初学装饰器时花费了数天时间,看了不同讲师对这块内容的讲解,还是一知半解。


不过装饰器在开发中可是很好用的,有必要攻破,希望这篇文章能帮助学习者快速攻破难关。



初步理解

#先来看一个简单函数defshow():print(‘Mrtu‘)show()#执行结果:Mrtu#现在我们用装饰器扩展这个函数,在打印"Mrtu"之前打印一行"hello"defdecorate(fun1):defwapper():print(‘hello‘)fun1()returnwapper@decoratedefshow():print(‘Mrtu‘)show()#执行结果:helloMrtu#现在解释上面的代码。#1、首先defdecorate(fun1)定义一个装饰器函数,在此函数里又定义了一个wapper子函数,子函数可以继承父函数的参数。#2、@‘函数名‘是Python的一种语法糖@decorate等于decorate(show)#还是晕,不明白?没关系,看下面代码:defdecorate(fun1):defwapper():print(‘hello‘)fun1()returnwapperdefshow():print(‘Mrtu‘)f1=decorate(show)f1()#执行结果:helloMrtu#换成这种写法,执行效果是一样的,因为这就是@decorate的本质。#就是将被装饰器装饰的函数show作为参数传给装饰器函数。#总结执行过程:#1、show函数作为参数传给装饰器函数decorate,那么fun1=show#2、这时执行到装饰器的子函数wapper,子函数可以继承父函数的参数,所以可以调用fun1#3、然后wapper函数执行print打印一行"hello",再然后调用fun1()——这里其实就是执行了show函数。因为在装饰器一开始执行的时候就把show函数作为参数赋值给了fun1.#现在明白了吧,只要这里明白,下面的就很好理解了。



装饰带参数的函数

#一个参数defdecorate(fun1):defwapper(arg1):print(‘hello‘)fun1(arg1)print(‘nicetomeetyou‘)returnwapper@decoratedefshow(arg1):print(arg1)show(‘MrAlice‘)#执行结果:helloMrAlicenicetomeetyou#两个参数defdecorate(fun1):defwapper(arg1,arg2):print(‘hello‘)fun1(arg1,arg2)print(‘nicetomeetyou‘)returnwapper@decoratedefshow(arg1,arg2):print(arg1,arg2)show(‘MrAlice‘,‘MrTom‘)#执行结果:hello(‘MrAlice‘,‘MrTom‘)nicetomeetyou#n个参数defdecorate(fun1):defwapper(*args,**kwargs):print(‘hello‘)fun1(*args,**kwargs)print(‘nicetomeetyou‘)returnwapper@decoratedefshow(*args,**kwargs):print(args[0])print(args[1])print(args[2])show(‘MrAlice‘,‘MrTim‘,‘Mrtu‘)#执行结果:helloMrAliceMrTimMrtunicetomeetyou


一个函数被多个装饰器装饰

defdecorate01(fun1):defwapper(*args,**kwargs):print(‘helloworld‘)print(‘Iamdecorate01‘)fun1(*args,**kwargs)returnwapperdefdecorate02(fun1):defwapper(*args,**kwargs):print(‘Iamdecorate02‘)fun1(*args,**kwargs)print(‘nicetomeetyou‘)returnwapper@decorate01@decorate02defshow(*args,**kwargs):print(args[0])print(args[1])print(args[2])show(‘MrAlice‘,‘MrTim‘,‘Mrtu‘)#执行结果:helloworldIamdecorate01Iamdecorate02MrAliceMrTimMrtunicetomeetyou#观察print放置的位置不同,对应的输出结果不同。defdecorate01(fun1):defwapper(*args,**kwargs):print(‘helloworld‘)fun1(*args,**kwargs)print(‘Iamdecorate01‘)#替换到了下面returnwapperdefdecorate02(fun1):defwapper(*args,**kwargs):print(‘Iamdecorate02‘)fun1(*args,**kwargs)print(‘nicetomeetyou‘)returnwapper@decorate01@decorate02defshow(*args,**kwargs):print(args[0])print(args[1])print(args[2])show(‘MrAlice‘,‘MrTim‘,‘Mrtu‘)#执行结果:helloworldIamdecorate02MrAliceMrTimMrtunicetomeetyouIamdecorate01


装饰器功能扩展

#!/usr/local/python27/bin/python2.7defbefore(request,*args,**kwargs):print(‘before‘)defafter(request,*args,**kwargs):print(‘after‘)defFilter(before_func,after_func):defouter(fun1):defwapper(request,*args,**kwargs):before_result=before_func(request,*args,**kwargs)if(before_result!=None):returnbefore_result;fun1_result=fun1(request,*args,**kwargs)if(fun1_result!=None):returnfun1_result;after_result=after_func(request,*args,**kwargs)if(after_result!=None):returnafter_result;returnwapperreturnouter@Filter(before,after)defshow(request,*args,**kwargs):print(‘Mrtu‘)show(‘1‘)#执行结果:beforeMrtuafter


函数若未定义返回值,执行成功返回值默认为 None ,这里的语句 if (before_result != None) 意思就是before函数执行失败时采取什么操作。


本文出自 “突破舒适区” 博客,请务必保留此出处http://tchuairen.blog.51cto.com/3848118/1843966

Python 如何理解又晕又好用的装饰器

评论关闭