加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python装饰器的实现

发布时间:2020-12-17 00:17:40 所属栏目:Python 来源:网络整理
导读:div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?opt=1"gt; p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;"说起装饰器我们可能已

<div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?opt=1"&gt;
<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"&gt;python基础学习——装饰器),随手就可以写一个简单的装饰器

 :
     :
        
        result = func(*args,**kwargs)
        
         result
     inner

方法吗

 :
     :
        self.func = func
<span class="hljs-function" style="color: #bbdaff;"&gt;<span class="hljs-keyword" style="color: #ebbbff;"&gt;def</span> <span class="hljs-title" style="color: #7285b7;"&gt;__call__</span><span class="hljs-params" style="color: #ffc58f;"&gt;(self,*args,**kwargs)</span>:</span>
    <span class="hljs-comment" style="color: #7285b7;"&gt;# 执行函数前做点事</span>
    result = self.func(*args,**kwargs)
    <span class="hljs-comment" style="color: #7285b7;"&gt;# 执行函数后干点啥</span>
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;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;">在装饰器中,我们在被装饰函数执行前会做一些事,在被装饰函数执行后可能也会做一些事,可是按照上面的写法,这些事情都是固定写好的,可不可以让这些动作会自定义的做些区别变化,那么参数化的装饰器能够满足这个要求

 ):
     :
         :
            
            print(what_i_say)
            result = func(*args,**kwargs)
            
             result
         inner
     actual_decorator

<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;">在使用装饰器后一段时间,可能有一天我们会突然发现一点不对劲的地方,比如我们打印被装饰的函数的时候

.actual_decorator..inner at 0x00000211E632CB70>

 functools  wraps

<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"&gt;@wraps(func)</span>
    <span class="hljs-function" style="color: #bbdaff;"&gt;<span class="hljs-keyword" style="color: #ebbbff;"&gt;def</span> <span class="hljs-title" style="color: #7285b7;"&gt;inner</span><span class="hljs-params" style="color: #ffc58f;"&gt;(*args,**kwargs)
        <span class="hljs-comment" style="color: #7285b7;"&gt;# 执行函数后干点啥</span>
        <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> result
    <span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> inner
<span class="hljs-keyword" style="color: #ebbbff;"&gt;return</span> actual_decorator


<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">我们从functools模块中引入了wraps()装饰器,用它来装饰装饰器中的inner函数,这样再次使用这个装饰器去装饰函数,它的元数据就保留下来了


 :
     a + b

print(add)

<span class="hljs-comment" style="color: #7285b7;"># <function add at 0x000001F5DEE966A8>


<div style="height: 0; width: 0; max-height: 0; max-width: 0; overflow: hidden; font-size: 0em; padding: 0; margin: 0;" title="MDH:PHA+6K+06LW36KOF6aWw5Zmo5oiR5Lus5Y+v6IO95bey57uP5b6I54af5oKJ5LqG77yI5LiN5LqG
6Kej55qE5Y+v5Lul5p+l55yLPGEgZGF0YS1tY2UtaHJlZj0iaHR0cHM6Ly93d3cuY25ibG9ncy5j
b20vc2ZlbmNzLWhjeS9wLzk2MTU2NTEuaHRtbCIgaHJlZj0iaHR0cHM6Ly93d3cuY25ibG9ncy5j
b20vc2ZlbmNzLWhjeS9wLzk2MTU2NTEuaHRtbCIgdGFyZ2V0PSJfYmxhbmsiIHN0eWxlPSIiPnB5
dGhvbuWfuuehgOWtpuS5oC0tLS3oo4XppbDlmag8L2E+77yJ77yM6ZqP5omL5bCx5Y+v5Lul5YaZ
5LiA5Liq566A5Y2V55qE6KOF6aWw5ZmoPC9wPjxwPmBgYHB5dGhvbjwvcD48cHJlPmRlZiBkZWNv
cmF0b3IoZnVuYyk6PGJyPiAgICBkZWYgaW5uZXIoKmFyZ3MsICoqa3dhcmdzKTo8YnI+ICAgICAg
ICAjIOaJp+ihjOWHveaVsOWJjeWBmueCueS6izxicj4gICAgICAgIHJlc3VsdCA9IGZ1bmMoKmFy
Z3MsICoqa3dhcmdzKTxicj4gICAgICAgICMg5omn6KGM5Ye95pWw5ZCO5bmy54K55ZWlPGJyPiAg
ICAgICAgcmV0dXJuIHJlc3VsdDxicj4gICAgcmV0dXJuIGlubmVyPC9wcmU+PHA+YGBgPC9wPjxw
PuS9huaYr+ijhemlsOWZqOeahOWunueOsOWPr+S4jeaYr+WPquaciei/meS4gOenje+8jOivt+ec
i+S4i+mdojwvcD48cD4jIOmAmui/h+exu+adpeWunueOsDwvcD48cD7kuIrpnaLlhpnnmoToo4Xp
pbDlmajmmK/nlLHlh73mlbDnmoTmlrnlvI/lrp7njrDnmoTvvIzkvYbmiJHku6zkuZ/lj6/ku6Xn
lKjnsbvnmoTmlrnlvI/lhpnkuIDkuKrlkIzmoLfnmoToo4XppbDlmajvvIzov5jorrDlvpdfX2Nh
bGxfX+aWueazleWQlzwvcD48cD5gYGBweXRob248L3A+PHByZT5jbGFzcyBkZWNvcmF0b3I6PGJy
PiAgICBkZWYgX19pbml0X18oc2VsZixmdW5jKTo8YnI+ICAgICAgICBzZWxmLmZ1bmMgPSBmdW5j
PGJyPjxicj4gICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzLCAqKmt3YXJncyk6PGJyPiAgICAg
ICAgIyDmiafooYzlh73mlbDliY3lgZrngrnkuos8YnI+ICAgICAgICByZXN1bHQgPSBzZWxmLmZ1
bmMoKmFyZ3MsICoqa3dhcmdzKTxicj4gICAgICAgICMg5omn6KGM5Ye95pWw5ZCO5bmy54K55ZWl
PGJyPiAgICAgICAgcmV0dXJuIHJlc3VsdDwvcHJlPjxwPmBgYDwvcD48cD7mr5TlpoLmnInkuIDk
uKphZGQoKeWHveaVsOiiq+ijhemlsO+8jOWFtuWunuebuOW9k+S6jmFkZCA9IGRlY29yYXRvcihh
ZGQpLOmCo+S5iGRlY29yYXRvcihhZGQp5bCx5piv6L+Z5Liq57G755qE5a6e5L6L77yMIOaJp+ih
jGFkZChhLGIp55qE5pe25YCZ5bCx5piv5omn6KGMX19jYWxsX1/mlrnms5XkuoY8L3A+PHA+IyDl
j4LmlbDljJbnmoToo4XppbDlmag8L3A+PHA+5Zyo6KOF6aWw5Zmo5Lit77yM5oiR5Lus5Zyo6KKr
6KOF6aWw5Ye95pWw5omn6KGM5YmN5Lya5YGa5LiA5Lqb5LqL77yM5Zyo6KKr6KOF6aWw5Ye95pWw
5omn6KGM5ZCO5Y+v6IO95Lmf5Lya5YGa5LiA5Lqb5LqL77yM5Y+v5piv5oyJ54Wn5LiK6Z2i55qE
5YaZ5rOV77yM6L+Z5Lqb5LqL5oOF6YO95piv5Zu65a6a5YaZ5aW955qE77yM5Y+v5LiN5Y+v5Lul
6K6p6L+Z5Lqb5Yqo5L2c5Lya6Ieq5a6a5LmJ55qE5YGa5Lqb5Yy65Yir5Y+Y5YyW77yM6YKj5LmI
5Y+C5pWw5YyW55qE6KOF6aWw5Zmo6IO95aSf5ruh6Laz6L+Z5Liq6KaB5rGCPC9wPjxwPmBgYHB5
dGhvbjwvcD48cHJlPmRlZiBkZWNvcmF0b3Iod2hhdF9pX3NheT0n5oiR5LuA5LmI5Lmf5rKh6K+0
Jyk6PGJyPiAgICBkZWYgYWN0dWFsX2RlY29yYXRvcihmdW5jKTo8YnI+ICAgICAgICBkZWYgaW5u
ZXIoKmFyZ3MsICoqa3dhcmdzKTo8YnI+ICAgICAgICAgICAgIyDmiafooYzlh73mlbDliY3lgZrn
grnkuos8YnI+ICAgICAgICAgICAgcHJpbnQod2hhdF9pX3NheSk8YnI+ICAgICAgICAgICAgcmVz
dWx0ID0gZnVuYygqYXJncywgKiprd2FyZ3MpPGJyPiAgICAgICAgICAgICMg5omn6KGM5Ye95pWw
5ZCO5bmy54K55ZWlPGJyPiAgICAgICAgICAgIHJldHVybiByZXN1bHQ8YnI+ICAgICAgICByZXR1
cm4gaW5uZXI8YnI+ICAgIHJldHVybiBhY3R1YWxfZGVjb3JhdG9yPGJyPjxicj48YnI+QGRlY29y
YXRvcign5oiR6KaB5YGa5LiA5qyh5Yqg5rOVJyk8YnI+ZGVmIGFkZChhLCBiKTo8YnI+ICAgIHJl
dHVybiBhICsgYjxicj48YnI+PGJyPnByaW50KGFkZCgzLCA5KSk8L3ByZT48cD5gYGA8L3A+PHA+
5pyJ5LqG6L+Z5Liq5Y+C5pWw5YyW6KOF6aWw5Zmo77yM5oiR5Lus5bCx5Y+v5Lul5Zyo6KOF6aWw
5Ye95pWw5pe25bCG5Y+C5pWw5YaZ5Zyo5ous5Y+35YaF77yM5Lmf5bCx5piv5Lyg5YWl5Y+C5pWw
77yI6L+Z6YeM5oiR5Lyg55qE5piv5a2X56ym5Liy77yM5YW25a6e5rKh5ZWl5oSP5LmJ77yM5Y+q
5piv5Li65LqG566A5Y2V6KGo56S65Y+C5pWw77yJPC9wPjxwPuS9huaYr+aIkeS7rOeci+WIsOi/
meS4quijhemlsOWZqOeahOWunueOsOS4reWHuueOsOS6huS4ieasoWRlZu+8jOS5i+WJjeeahOS4
jemDveaYr+WHuueOsOS4pOasoeWQl++8jOi/measoeaAjuS5iOWHuueOsOS6hjPmrKHvvJ/lroPm
mK/mgI7kuYjmiafooYznmoQ8L3A+PHA+5YW25a6e56iN5b6u5oOz5LiA5LiL5bCx5oOz6YCa5LqG
77yM6L+Y5piv5oyJ54Wn6KOF6aWw55qE6L+H56iL5p2lPC9wPjxwPuS5i+WJjeaYr2FkZCA9IGRl
Y29yYXRvcihhZGQp77yM6L+Z5qyh5bCx5oqKZGVjb3JhdG9y5o2i5oiQZGVjb3JhdG9yKCfmiJHo
poHlgZrkuIDmrKHliqDms5UnKe+8jGFkZCA9IGRlY29yYXRvcign5oiR6KaB5YGa5LiA5qyh5Yqg
5rOVJykoYWRkKe+8jOeUseS6juWHveaVsOaYr+S4gOetieWvueixoe+8jOaJgOS7pWRlY29yYXRv
cign5oiR6KaB5YGa5LiA5qyh5Yqg5rOVJynlsLHmmK/oo4XppbDlmajkuK3nrKzkuIDmrKHov5Tl
m57nmoRhY3R1YWxfZGVjb3JhdG9y77yM55Sx5LqO6Zet5YyF55qE54m55oCn77yM5Lyg6YCS55qE
5Y+C5pWw57uR5a6a5Yiw5LqG5YaF6YOo5Ye95pWw5Lit77yM5omA5LulZGVjb3JhdG9y5omn6KGM
5a6M5ZCO77yM5Lyg5YWl55qEJ+aIkeimgeWBmuS4gOasoeWKoOazlSfov5jmmK/lj6/ku6XmiZPl
jbDlh7rmnaXjgII8L3A+PHA+5omA5Lul6L+Z5Liq5Y+C5pWw5YyW55qE6KOF6aWw5Zmo5ZKM5pmu
6YCa55qE6KOF6aWw5Zmo6KOF6aWw55qE6L+H56iL5piv5LiA5qC355qE44CCPC9wPjxwPiMg5L+d
5a2Y5Ye95pWw5YWD5pWw5o2u55qE6KOF6aWw5ZmoPC9wPjxwPuWcqOS9v+eUqOijhemlsOWZqOWQ
juS4gOauteaXtumXtO+8jOWPr+iDveacieS4gOWkqeaIkeS7rOS8mueqgeeEtuWPkeeOsOS4gOeC
ueS4jeWvueWKsueahOWcsOaWue+8jOavlOWmguaIkeS7rOaJk+WNsOiiq+ijhemlsOeahOWHveaV
sOeahOaXtuWAmTwvcD48cD5gYGBweXRob248L3A+PHByZT5wcmludChhZGQpPGJyPiMmbHQ7ZnVu
Y3Rpb24gZGVjb3JhdG9yLiZsdDtsb2NhbHMmZ3Q7LmFjdHVhbF9kZWNvcmF0b3IuJmx0O2xvY2Fs
cyZndDsuaW5uZXIgYXQgMHgwMDAwMDIxMUU2MzJDQjcwJmd0Ozxicj48L3ByZT48cD5gYGA8L3A+
PHA+5ZKm77yM5LiN5a+55ZWK77yM5oCO5LmI5a6D55qE5ZCN5a2X5LiN5pivYWRk6ICM5pivZGVj
b3JhdG9yLiZsdDtsb2NhbHMmZ3Q7LmFjdHVhbF9kZWNvcmF0b3IuJmx0O2xvY2FscyZndDsuaW5u
ZXLov5nkuKrnjqnmhI/jgILmiJHku6zku5Tnu4bkuIDor7vmg7PotbfmnaXkuobvvIzov5nmmK/o
oqvoo4XppbDlmajoo4XppbDkuobnmoTpgqPkuKrlh73mlbDvvIzmiYDku6XlroPmioroo4XppbDl
majph4znmoTpgqPkuKrnu5nmiZPljbDlh7rmnaXkuobjgILlj6/mmK/miorov5nkuKrnjqnmhI/m
iZPljbDlh7rmnaXlubLlmJvlkYDvvIzmiJHopoHljp/mnaXnmoTlh73mlbDlkI3vvIzmnInmsqHm
nInku4DkuYjlip7ms5XllYrvvIzlip7ms5XlvZPnhLbmnInvvIzlpoLkuIs8L3A+PHA+YGBgcHl0
aG9uPC9wPjxwcmU+ZnJvbSBmdW5jdG9vbHMgaW1wb3J0IHdyYXBzPGJyPjxicj5kZWYgZGVjb3Jh
dG9yKHdoYXRfaV9zYXkpOjxicj4gICAgZGVmIGFjdHVhbF9kZWNvcmF0b3IoZnVuYyk6PGJyPjxi
cj4gICAgICAgIEB3cmFwcyhmdW5jKTxicj4gICAgICAgIGRlZiBpbm5lcigqYXJncywgKiprd2Fy
Z3MpOjxicj4gICAgICAgICAgICAjIOaJp+ihjOWHveaVsOWJjeWBmueCueS6izxicj4gICAgICAg
ICAgICBwcmludCh3aGF0X2lfc2F5KTxicj4gICAgICAgICAgICByZXN1bHQgPSBmdW5jKCphcmdz
LCAqKmt3YXJncyk8YnI+ICAgICAgICAgICAgIyDmiafooYzlh73mlbDlkI7lubLngrnllaU8YnI+
ICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDxicj4gICAgICAgIHJldHVybiBpbm5lcjxicj4gICAg
cmV0dXJuIGFjdHVhbF9kZWNvcmF0b3I8L3ByZT48cD5gYGA8L3A+PHA+5oiR5Lus5LuOZnVuY3Rv
b2xz5qih5Z2X5Lit5byV5YWl5LqGd3JhcHMoKeijhemlsOWZqO+8jOeUqOWug+adpeijhemlsOij
hemlsOWZqOS4reeahGlubmVy5Ye95pWw77yM6L+Z5qC35YaN5qyh5L2/55So6L+Z5Liq6KOF6aWw
5Zmo5Y676KOF6aWw5Ye95pWw77yM5a6D55qE5YWD5pWw5o2u5bCx5L+d55WZ5LiL5p2l5LqGPC9w
PjxwPmBgYHB5dGhvbjwvcD48cHJlPkBkZWNvcmF0b3IoJ+aIkeimgeWBmuS4gOasoeWKoOazlScp
PGJyPmRlZiBhZGQoYSwgYik6PGJyPiAgICByZXR1cm4gYSArIGI8YnI+PGJyPnByaW50KGFkZCk8
L3ByZT48cD4jJm5ic3A7Jmx0O2Z1bmN0aW9uIGFkZCBhdCAweDAwMDAwMUY1REVFOTY2QTgmZ3Q7
PC9wPjxwPmBgYDwvcD48cD48YnIgZGF0YS1tY2UtYm9ndXM9IjEiPjwvcD4=">?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读