在代理中託管特殊方法的python代碼實現

任務簡單的介紹是: 在新風格對象模型中,Python操做實際上是在類中查找特殊方法的(經典對象是在實例中進行操做的),如今須要將一些新風格的實例包裝到代理中,,此代理能夠選擇將一些特殊的方法委託給內部的被包裝對象。python

代碼實施爲:緩存

 1 class Proxy(object):
 2     """全部代理的基類"""
 3     def __init__(self, obj):
 4         super(Proxy, self).__init__()  #少了此補會致使無限遞歸循環
 5         self._obj = obj
 6     
 7     def __getattr__(self, attribute):
 8         return getattr(self._obj, attribute)
 9 
10 
11 def make_binder(unbound_method):
12        def wrapper(self, *arg, **kwargs):
13            return unbound_method(self._obj, *arg, **kwargs)
14        return wrapper
15 
16 
17 known_proxy_classes = {}
18 
19 
20 def proxy(obj, *specials):
21     """工廠函數"""
22     obj_cls = obj.__class__
23     key = obj_cls, specials
24     cls = known_proxy_classes.get(key)
25     if cls is None:
26         cls = type("%sProxy" % ob_cls.__name, (Proxy,), {})
27         for name in specials:
28             name = '__%s__' % name
29             unbound_method = getattr(obj_cls, name)
30             setattr(cls, name, make_binder(unbound_method))
31        """緩存之以供進一步使用
32        known_proxy_classes[key] = cls
33      """實例化並返回須要的代理
34     return cls(obj)        

  代理(以及自動託管)都得歸功於__getattr__機制,在查詢任何屬性時,(包括方法,python並不區分二者),python都會自動調用__getattr__。app

  代碼運行結果以下圖:函數

    其實結果很容易理解,就是經過特殊方法代理實現子類方法的代理,例如上面實例,因爲代理了list中的len和iter,那麼能夠實現方法len以及迭代,沒有代理geiitem方法,那麼在利用index時就會報錯。spa

  在新風格對象中,python操做並不會在運行的時候查找特殊方法:它們依賴於類對象的「槽」。而這些槽會在對象被建立或者修改的時候更新,所以,對於一個代理對象,若是它要把特殊方法託管給被封裝的對象,它自己必須屬於某個量身定作的類。代理

相關文章
相關標籤/搜索