Python高级编程——装饰器Decorator详解(中篇)(绝对是我见过最详细的的教程,没有之一哦)

论坛 期权论坛     
匿名小用户   2019-10-20 22:56   3329   0
<p><img alt="" class="blockcode" src="https://201907.oss-cn-shanghai.aliyuncs.com/cs/5606289-cfb795dd6f01053f2f3c94eb49a1da4b.png"></p>

<p><img alt="" class="blockcode" src="https://201907.oss-cn-shanghai.aliyuncs.com/cs/5606289-1799a6f507c4ee9cc5f8a6d531db5d52.png"></p>

<p><span style="color:#f33b45;"><strong>声明:</strong></span>此文章为,python装饰器详解——中篇,上一篇文章中,即详解装饰器——上篇 ,已经详细讲解了装饰器诞生的背景,装饰器的定义、作用、应用场景,本文将以实际例子为依托,深入详解装饰器的各类实现(包括<span style="color:#f33b45;"><strong>函数装饰器、类装饰器、闭包、装饰器的嵌套</strong></span>四大块内容)系列文章共分为 上、中、下 三篇。此为第二篇。</p>

<h2><span style="color:#f33b45;">一、函数装饰器</span></h2>

<p>前面提到过,装饰器分为函数装饰器、类装饰器,本节详细解释函数装饰器,又分为两种情况,因为函数装饰器可以装饰函数,也可以装饰类。<span style="color:#f33b45;">函数装饰器是最常见的</span>,故而最先讨论。</p>

<p><span style="color:#f33b45;"><strong>注意</strong></span>:因为没有参数,且无函数返回值的函数是最为简单的,就如“上篇”所讨论的那样,这里就不再叙述了,本文主要讲的都是函数带有参数,而且具有函数返回值的函数。</p>

<p><span style="color:#f33b45;"><strong>1、函数装饰器 装饰一个函数</strong></span></p>

<p>假定有一个函数实现两个数的相加,a+b,但是为了对这两个数相加的结果进行加密,我们需要给函数添加额外的代码,但是我们通过装饰器去实现,要达到的效果是,不是直接返回a+b的结果,而是进行进一步处理。代码如下:</p>

<pre class="blockcode">
<code class="language-python">def MethodDecoration(function):  #外层decorator
    c=150
    d=200
    def wrapper(a,b):            #内层wrapper。和add_function参数要一样
        result=function(a,b)
        result=result*c/d        #加密,相当于添加额外功能
        return result            #此处一定要返回值
    return wrapper

@MethodDecoration
def add_function(a,b):
    return a+b


result=add_function(100,300)    #函数调用
print(result)</code></pre>

<p>运行结果为:300 (即(100+300)*150/200)</p>

<p>因为函数装饰器去装饰函数最为常见,所以这里就不多再解释了,按照前面上篇所讲的模板来即可,但是因为被装饰的函数有参数,而且具有返回值,有<span style="color:#f33b45;"><strong>两个点需要注意的</strong></span>,</p>

<p><span style="color:#f33b45;">第一:wrapper需要保证与add_function参数一致。</span>因为返回的wrapper就是add_function,所以要统一,我们可以使用*arg,和**args去匹配任何参数;</p>

<p><span style="color:#f33b45;">第二:wrapper一定要返回值。</span>因为add_function函数是需要返回值的。</p>

<p><span style="color:#f33b45;"><strong>2、函数装饰器 装饰一个类</strong></span></p>

<p>在Python中,从某种意义上来说,函数和类是一样的,因为它们都是对象(python一切皆对象),故而decorator的参数理所当然也可以传入一个类了。其中最经典的应用,就是使用装饰器构造“单例模式”(不明白单例模式的小伙伴可以参见下面这篇博文哦)</p>

<p><a data-token="675b1896506694bda43fdeda85aa52f3" href="https://blog.csdn.net/qq_27825451/article/details/84135466" rel="nofollow">一文详解“单例模式”及其python语言的实现</a></p>

<p>代码如下:</p>

<pre class="blockcode">
<code class="language-python">defSingleton(cls):#这是第一层函数,相当于模板中的Decorator.目的是要实现一个“装饰器”,而且是对类型的装饰器
'''
cls:表示一个类名,即所要设计的单例类名称,
因为python一切皆对象,故而类名同样可以作为参数传递
'''
instance={}

defsingleton(*args,**kargs):  #这是第二层,相当于wrapper,要匹配参数
ifclsnotininstance:
instance[cls]=cls(*args,**kargs)#如果没有cls这个类,则创建,并且将这个cls所创建的实例,保存在一个字典中
returninstance[cls]        #返回创建的对象

returnsingleton

@Singleton
classStudent(object):
def__init__(self,name,age):
self.name=name
self.age=age

s1=Student('张三',23)
s2=Student('李四',24)
print((s1==s2))
print(s1iss2)
print(id(s1),id(s2),sep='')
</code></pre>

<p>上面运行的结果是:</p>

<p>True<br>
True<br>
2150787003840  2150787003840</p>

<p>懂得单例模式的小伙伴可能一看就明白了,上面的实现和我前面讲过的“装饰器模板”,基本上一样,<span style="color:#f33b45;">第一层、第二层、返回值、参数匹配</span>等。但是有的小伙伴可能会问,这里我没有看到“添
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:50
帖子:1079
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP