|
<div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?opt=1">
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">说起装饰器我们可能已经很熟悉了(不了解的可以查看<a href="https://www.cnblogs.com/sfencs-hcy/p/9615651.html">python基础学习——装饰器),随手就可以写一个简单的装饰器
<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def</span> <span class="hljs-title" style="color: #7285b7;">__call__</span><span class="hljs-params" style="color: #ffc58f;">(self,*args,**kwargs)</span>:</span>
<span class="hljs-comment" style="color: #7285b7;"># 执行函数前做点事</span>
result = self.func(*args,**kwargs)
<span class="hljs-comment" style="color: #7285b7;"># 执行函数后干点啥</span>
<span class="hljs-keyword" style="color: #ebbbff;">return</span> result
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">比如有一个add()函数被装饰,其实相当于add = decorator(add),那么decorator(add)就是这个类的实例, 执行add(a,b)的时候就是执行<strong style="color: #bf360c;">call方法了
<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">参数化的装饰器
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">在装饰器中,我们在被装饰函数执行前会做一些事,在被装饰函数执行后可能也会做一些事,可是按照上面的写法,这些事情都是固定写好的,可不可以让这些动作会自定义的做些区别变化,那么参数化的装饰器能够满足这个要求
<span class="hljs-decorator">@decorator('我要做一次加法')
<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def <span class="hljs-title" style="color: #7285b7;">add<span class="hljs-params" style="color: #ffc58f;">(a,b):
<span class="hljs-keyword" style="color: #ebbbff;">return a + b
print(add(<span class="hljs-number" style="color: #ffc58f;">3,<span class="hljs-number" style="color: #ffc58f;">9))
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">有了这个参数化装饰器,我们就可以在装饰函数时将参数写在括号内,也就是传入参数(这里我传的是字符串,其实没啥意义,只是为了简单表示参数)
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">但是我们看到这个装饰器的实现中出现了三次def,之前的不都是出现两次吗,这次怎么出现了3次?它是怎么执行的
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">其实稍微想一下就想通了,还是按照装饰的过程来
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">之前是add = decorator(add),这次就把decorator换成decorator(‘我要做一次加法’),add = decorator(‘我要做一次加法’)(add),由于函数是一等对象,所以decorator(‘我要做一次加法’)就是装饰器中第一次返回的actual_decorator,由于闭包的特性,传递的参数绑定到了内部函数中,所以decorator执行完后,传入的’我要做一次加法’还是可以打印出来。
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">所以这个参数化的装饰器和普通的装饰器装饰的过程是一样的。
<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">保存函数元数据的装饰器
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">在使用装饰器后一段时间,可能有一天我们会突然发现一点不对劲的地方,比如我们打印被装饰的函数的时候
.inner at 0x00000211E632CB70>
<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def <span class="hljs-title" style="color: #7285b7;">decorator<span class="hljs-params" style="color: #ffc58f;">(what_i_say):
<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def <span class="hljs-title" style="color: #7285b7;">actual_decorator<span class="hljs-params" style="color: #ffc58f;">(func):
<span class="hljs-decorator">@wraps(func)</span>
<span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def</span> <span class="hljs-title" style="color: #7285b7;">inner</span><span class="hljs-params" style="color: #ffc58f;">(*args,**kwargs)
<span class="hljs-comment" style="color: #7285b7;"># 执行函数后干点啥</span>
<span class="hljs-keyword" style="color: #ebbbff;">return</span> result
<span class="hljs-keyword" style="color: #ebbbff;">return</span> inner
<span class="hljs-keyword" style="color: #ebbbff;">return</span> actual_decorator
(编辑:安卓应用网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|