2009-09-24 46 views
1

我想要一個Python類,充當另一個Python類的包裝。在Python中創建一個門面2.5

像這樣的事情

class xxx: 
    name = property(fset=lambda self, v: setattr(self.inner, 'name', v), fget=lambda self: getattr(self.inner, 'name')) 

    def setWrapper(self, obj) 
     self.inner = obj 

所以當有人說XXX()X = '你好',我希望它設置XXX()的值。inner.whatever,而不是演XXX()X。

這可能嗎?我一直在嘗試lambda,但無濟於事。我正在使用Python 2.5

編輯: 現在我的妻子並沒有讓我睡覺,所以我可以更多地清理代碼。我有點想到你們下面有什麼,但從docs看來,你應該避免重寫__setattr__/__getattr__並使用屬性。如果通過屬性功能無法做到這一點,那麼我將使用__setattr__/__getattr__?謝謝

回答

6

這是您使用__setattr____getattr__方法的地方,如記錄here

總之,如果你這樣做:

class Wrapper(object): 
    def __init__(self, wrapped): 
     object.__setattr__(self, 'inner', wrapped) 

    def __getattr__(self, attr): 
     return getattr(self.inner, attr) 

    def __setattr__(self, attr, value): 
     setattr(self.inner, attr, value) 

它應該做你以後。我強烈建議閱讀與上面鏈接的文檔。

編輯:正如指出的,原來的版本失敗,因爲__setattr__被無條件地調用。我已經更新了這個例子。請注意,此版本依賴於新風格的類行爲(如從對象的子類表示)。對於老式我想你需要惹__dict__如下:

class OldStyleWrapper: 
    def __init__(self, wrapped): 
     self.__dict__['inner'] = wrapped 

    def __getattr__(self, attr): 
     return getattr(self.inner, attr) 

    def __setattr__(self, attr, value): 
     setattr(self.inner, attr, value) 
5

作爲另一個答案說,__getattr____setattr__是關鍵,你使用後者時需要人照顧...:

class Wrapper(object): 
    def __init__(self, wrapped): 
     object.__setattr__(self, 'inner', wrapped) 

    def __getattr__(self, n): 
     return getattr(self.inner, n) 

    def __setattr__(self, n, value): 
     setattr(self.inner, n, value) 

你不需要爲self.inner訪問預防措施,因爲__getattr__被調用僅適用於不以其他方式存在的屬性;但__setattr__會從object呼籲每個屬性,所以當你真正需要設置self.inner(或任何其他屬性),你需要__setattr__(這裏我使用object爲宗旨,以明確繞過,所以我也繼承 - 高度無論如何,在Python 2. *中,否則你會做一個「舊式類」[[AT LAST在Python 3中消失的類]],你真的不想這樣做。 .. ;-)。

+0

好一點,我已經編輯我的例子,以配合你的。 =) – Benno 2009-09-24 03:31:37

0

相信無論是亞歷克斯和Ben的回答如下應該修改自己的電話的setattr:

setattr(self.inner, n, value)