亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

分析Python中設計模式之Decorator裝飾器模式的要點

2020-01-04 17:40:33
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Python中設計模式之Decorator裝飾器模式模式,文中詳細地講解了裝飾對象的相關加鎖問題,需要的朋友可以參考下
 

先給出一個四人團對Decorator mode的定義:動態地給一個對象添加一些額外的職責。
再來說說這個模式的好處:認證,權限檢查,記日志,檢查參數,加鎖,等等等等,這些功能和系統業務無關,但又是系統所必須的,說的更明白一點,就是面向方面的編程(AOP)。
在Python中Decorator mode可以按照像其它編程語言如C++, Java等的樣子來實現,但是Python在應用裝飾概念方面的能力上遠不止于此,Python提供了一個語法和一個編程特性來加強這方面的功能。Python提供的語法就是裝飾器語法(decorator),如下:

@aoodef foo(): passdef aoo(fn):  return fn

裝飾模式強調動態地給對象添加額外的功能。 Python內置了很多對裝飾器的支持,因此在Python中使用裝飾模式是非常容易的,下面是一個典型的例子,給函數增加日志功能:

import functoolsdef log_wrapper(fun): @functools.wraps(fun) def wrapper(*args, **kwargs):  print '在函數執行前加日志'  ret = fun(*args, **kwargs)  print '在函數執行后家日志'  return ret return wrapper@log_wrapperdef test(): print 'Hello, 世界'

functools.wraps是Python標準庫提供的一個特殊的裝飾器,用來解決裝飾器帶來的一些常規問題,如函數名稱、doc等的不一致問題。@是Python針對裝飾器提供的一個語法糖,上面的@log_wrapper相當于wrap_test = log_rapper(test),用@后,這個步驟由解釋器代勞了。

裝飾器是Python編程必須掌握的一項技能,在編碼過程中經常會用到。

這里只是一個普通的內嵌函數

def foo(x):  y = x  def foo1 ():    a = 1    return a  return foo1

而下面boo則是一個閉包

def aoo(a, b):  c = a  def boo (x):    x = b + 1    return x  return boo

boo的特殊性在于引用了外部變量b,當aoo返回后,只要返回值(boo)一直存在,則對b的引用就會一直存在。
上面的知識可能需要花些時間消化,如果你覺得已經掌握了這些知識,下面就回歸正題,看看這些語言特性是怎樣來實現Python中裝飾的概念的。
還是讓我們先看一個簡單的例子,然后逐步深入。這個例子就是加鎖,怎樣實現加鎖的功能?
具體需求是這樣的:我有一個對象,實現了某些功能并提供了一些接口供其它模塊調用,這個對象是運行在并發的環境中的,因此我需要對接口的調用進行同步,第一版的代碼如下:

class Foo(object):  def __init__(self, …):    self.lock = threading.Lock()  def interface1(self, …):    self.lock.acquire()    try:     do something    finally:     self.lock.release()  def interface2(self, …):    same as interface1()  …

這版代碼的問題很明顯,那就是每個接口函數都有相同的加鎖/解鎖代碼,重復的代碼帶來的是更多的鍵入,更多的閱讀,更多的維護,以及更多的修改,最主要的是,程序員本應集中在業務上的的精力被分散了,而且請注意,真正的業務代碼在距離函數定義2次縮進處開始,即使你的顯示器是寬屏,這也會帶來一些閱讀上的困難。
你直覺的認為,可以把這些代碼收進一個函數中,以達到復用的目的,但是請注意,這些代碼不是一個完整同一的代碼塊,而是在中間嵌入了業務代碼。
現在我們用裝飾器語法來改進這部分代碼,得到第2版代碼:

def sync(func): def wrapper(*args, **kv):   self = args[0]   self.lock.acquire()   try:    return func(*args, **kv)   finally:    self.lock.release() return wrapperclass Foo(object):  def __init__(self, …):    self.lock = threading.Lock()  @sync  def interface1(self, …):    do something  @sync  def interface2(self, …):    do something  …

一個裝飾器函數的第一個參數是所要裝飾的那個函數對象,而且裝飾器函數必須返回一個函數對象。如sync函數,當其裝飾interface1時,參數func的值就是interface1,返回值是wrapper,但類Foo實例的interface1被調用時,實際調用的是wrapper函數,在wrapper函數體中間接調用實際的interface1;當interface2被調用時,也調用的是wrapper函數,不過由于在裝飾時func已經變成interface2,所以會間接地調用到實際的interface2函數。
使用裝飾器語法的好處:
代碼量大大的減少了,更少的代碼意味著更少的維護,更少的閱讀,更少的鍵入,好處不一而足(可復用,可維護)
用戶基本上將絕大部分精力放在了業務代碼上,而且少了加減鎖的代碼,可讀性也提高了
缺點:
業務對象Foo中有一個非業務數據成員lock,很礙眼;
相當程度的耦合,wrapper的第一個參數必須是對象本身,而且被裝飾的對象中必須有一個lock對象存在,這給客戶對象添加了限制,使用起來不是很舒服。
我們可以更進一步想一想:
lock對象必須要放在Foo中嗎?
為每個接口函數都鍵入@sync還是很煩人的重復性人工工作,如果漏添加一個,還是會造成莫名其妙的運行時錯誤,為什么不集中處理呢?
為了解決上述的缺點,第3版代碼如下:

class DecorateClass(object): def decorate(self):  for name, fn in self.iter():   if not self.filter(name, fn):    continue   self.operate(name, fn)class LockerDecorator(DecorateClass): def __init__(self, obj, lock = threading.RLock()):  self.obj = obj  self.lock = lock def iter(self):  return [(name, getattr(self.obj, name)) for name in dir(self.obj)] def filter(self, name, fn):  if not name.startswith('_') and callable(fn):    return True  else:    return False def operate(self, name, fn):  def locker(*args, **kv):   self.lock.acquire()   try:    return fn(*args, **kv)   finally:    self.lock.release()  setattr(self.obj, name, locker)class Foo(object):  def __init__(self, …):    …    LockerDecorator(self).decorate()  def interface1(self, …):    do something  def interface2(self, …):    do something  …

對對象的功能裝飾是一個更一般的功能,不僅限于為接口加鎖,我用2個類來完成這一功能,DecorateClass是一個基類,只定義了遍歷并應用裝飾功能的算法代碼(template method),LockerDecorator實現了為對象加鎖的功能,其中iter是迭代器,定義了怎樣遍歷對象中的成員(包括數據成員和成員函數),filter是過濾器,定義了符合什么規則的成員才能成為一個接口,operate是執行函數,具體實施了為對象接口加鎖的功能。
而在業務類Foo的__init__函數中,只需要在最后添加一行代碼:LockerDecorator(self).decorate(),就可以完成為對象加鎖的功能。
如果你的對象提供的接口有特殊性,完全可以通過直接改寫filter或者繼承LockerDecorator并覆蓋filter的方式來實現;此外,如果要使用其他的裝飾功能,可以寫一個繼承自DecorateClass的類,并實現iter,filter和operate三個函數即可。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕久热精品在线视频| 亚洲性线免费观看视频成熟| 日韩免费av在线| 欧美精品福利视频| 成人免费在线网址| 在线视频欧美日韩精品| 97婷婷大伊香蕉精品视频| 久久97精品久久久久久久不卡| 国内免费久久久久久久久久久| 91成人精品网站| 亚洲综合第一页| 欧美性黄网官网| 久久视频国产精品免费视频在线| 国产精品视频99| 精品日韩中文字幕| 亚洲天堂免费视频| 国内自拍欧美激情| 欧美激情在线有限公司| 日韩中文在线中文网在线观看| 伊人久久精品视频| 国产午夜精品视频免费不卡69堂| 国产精品视频在线播放| 国产视频亚洲精品| 欧美激情精品久久久| 91精品国产高清自在线看超| 国产午夜精品一区理论片飘花| 亚洲精品美女在线观看播放| 欧美日韩亚洲精品内裤| 亚洲国产美女久久久久| 国产精品高清网站| 欧美成人在线免费| 欧美国产日韩一区二区在线观看| 亚洲一二三在线| 欧美激情视频在线观看| 国产日韩欧美在线视频观看| 亚洲热线99精品视频| 亚洲级视频在线观看免费1级| 国产免费一区二区三区香蕉精| 日韩中文字幕在线| 欧美性猛xxx| 国产精品一区二区三区毛片淫片| 777国产偷窥盗摄精品视频| 国产精品视频大全| 国产成人精品999| 欧美在线观看网址综合| 日韩亚洲欧美中文在线| 国产成人精品免高潮费视频| 国产精选久久久久久| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲第一色中文字幕| 国产精品国产三级国产aⅴ9色| 国产一区二区三区在线视频| 欧美裸体xxxx极品少妇| 欧美精品激情在线观看| 久久综合国产精品台湾中文娱乐网| 欧美激情亚洲另类| 国产ts一区二区| 亚洲最大福利视频网站| 日韩一区二区精品视频| 一区二区三区动漫| 91精品美女在线| 亚洲一区二区中文| 国产999精品久久久影片官网| 操人视频在线观看欧美| 97视频在线观看网址| 在线视频欧美日韩精品| 超碰精品一区二区三区乱码| 日韩中文字幕第一页| 成人午夜高潮视频| 欧美小视频在线观看| 97色在线观看免费视频| 亚洲精品视频在线观看视频| 欧美日韩在线免费观看| 亚洲精品自拍第一页| 久久久久久18| 米奇精品一区二区三区在线观看| 国产午夜精品全部视频在线播放| 亚洲国产精品一区二区三区| 亚洲精品综合精品自拍| 国产精品一区电影| 国产成人啪精品视频免费网| 国产99久久精品一区二区| 亚洲一区久久久| 日韩精品视频在线播放| 色悠悠国产精品| 亚洲第一精品夜夜躁人人躁| 国产欧美一区二区三区在线看| 欧美成年人视频网站| 97热在线精品视频在线观看| 欧美国产日韩免费| 亚洲va国产va天堂va久久| 亚洲第五色综合网| 黄色成人av在线| 日韩欧美视频一区二区三区| 欧美亚洲成人网| 久久久精品久久久| 日本不卡免费高清视频| 国产亚洲精品一区二555| 亚州av一区二区| 欧美日韩亚洲精品内裤| 国产精品三级久久久久久电影| 成人福利视频在线观看| 中文字幕国内精品| 亚洲欧美综合图区| 国产亚洲欧洲高清| 亚洲国产精品成人一区二区| 国产一区二区三区免费视频| 亚洲综合一区二区不卡| 中文.日本.精品| 性欧美长视频免费观看不卡| 91亚洲国产精品| 欧美性高跟鞋xxxxhd| 黑人巨大精品欧美一区二区一视频| 国产精品久久久久久久久久ktv| 国产成人精品国内自产拍免费看| 国产精品第一第二| 九九热精品在线| 成人免费黄色网| 国产精品免费看久久久香蕉| 久久亚洲欧美日韩精品专区| 精品一区二区三区三区| 国产深夜精品福利| 日本91av在线播放| 精品动漫一区二区| 日韩有码在线视频| 久久天堂av综合合色| 91亚洲精品久久久久久久久久久久| 黑人欧美xxxx| 亚洲国产天堂久久国产91| 成人在线小视频| 欧美激情久久久久久| 国产精品专区h在线观看| 亚洲欧洲第一视频| 欧美精品在线免费观看| 日韩性生活视频| 国产精品网址在线| 亚洲高清不卡av| 美女精品视频一区| 欧美多人爱爱视频网站| 欧美视频在线看| 国产精品女主播| 久久精品视频免费播放| 亲爱的老师9免费观看全集电视剧| 狠狠久久五月精品中文字幕| 日韩视频免费大全中文字幕| 97在线视频观看| 国产69精品久久久久9| 亚洲自拍偷拍网址| 日韩亚洲第一页| 欧美在线观看日本一区| 中文字幕日本精品| 欧美激情精品久久久久久大尺度| 92看片淫黄大片看国产片| 国语自产偷拍精品视频偷| 久久久久国产精品一区| 国产做受69高潮| 超在线视频97| 亚洲精品自拍第一页| 中文字幕一区二区精品| 欧美激情精品久久久久久大尺度| 欧美精品18videosex性欧美| 欧美成aaa人片在线观看蜜臀| 日韩免费观看高清| 色综合久综合久久综合久鬼88|