2012-02-07 40 views
6

概述:嵌套對象和SETATTR&GETATTR(是的,那就是時間)

class Inner(object): 
    def __init__(self, x): 
     self.x = x 

class Outer(object): 
    def __init__(self, z): 
     self.inner = Inner(z) 

o = Outer(10) 

現在,我想外部對象的行爲透明 - 在o設置的任何屬性都應當在o.inner設置,同爲閱讀:o.something應該返回,其實值爲o.inner.sommething。有點像代理或中繼。

__getattr__Outer看似簡單&作品:

def __getattr__(self, item): 
    return getattr(self, item) 

我將如何處理__setattr__?我無法想出任何不會導致遞歸錯誤並讓我恨自己的事情。

或者是概念本身有缺陷?

(我試過另一種方法是使OuterInner一個子類 - 這並沒有真正起到美觀本@classmethods,更不用說IDE會迷路內的 - 不能夠解決一些屬性讓我們離開那現在,也許呢?)

+0

你是不是指'self.inner = Inner(z)'?另外,你的getattr方法是否從Inner()返回數據?它的寫法是,它看起來像只是引用Outer。 – gfortune 2012-02-07 17:17:12

+0

是的 - 它確實會返回。修正了兩個,謝謝! – ntl0ve 2012-02-07 17:20:35

回答

7

棘手的部分是正確設置Outer類的inner屬性。你可以做的是調用object__setattribute__方法(基類的Outer):

class Inner(object): 
    def __init__(self, x): 
     self.x = x 

class Outer(object):  
    def __init__(self, z): 
     object.__setattr__(self, 'inner', Inner(z)) 

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

    def __setattr__(self, name, value): 
     return setattr(self.inner, name, value) 

現在,它工作正常:

o = Outer(10) 
print o.x  # 10 
print o.inner.x # 10 
o.g = 3 
print o.g  # 3 
print o.inner.g # 3 

但是,目前還不清楚我爲什麼不這樣做在這種情況下想要使用繼承。 Outer繼承自Inner似乎更自然和pythonic。

+0

而打印(o.inner)的原因是因爲o.inner已經存在,所以它不會調用'__getattr__'並嘗試返回o.inner.inner,是否正確?在所請求的項目已經作爲所討論的對象的一部分存在的情況下,並不明顯看到__getattr__沒有被調用。 – gfortune 2012-02-07 17:42:30

+0

@gfortune,是;爲更多看到[這個問題](http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute-in-python)。 – senderle 2012-02-07 17:51:39

+0

是的,請參閱[\ _ \ _ getattr \ _ \ _](http://docs.python.org/reference/datamodel.html#object.__getattr__)文檔 – jterrace 2012-02-07 18:00:37