2012-11-21 47 views
1

假設我有兩個Python類,A和B.我希望能夠做到以下幾點:動態添加類的實例,以Python實例點菜__setattr__

>>> b = B() 
>>> b.a.attr1 = 'foo' 
>>> b.a.attr2 = 'bar' 

其中「a」是的一個實例答:如果'a'是 「原始」類型,我不會像使用__setattr__一樣。是否有一些優雅的方式來實現這一點,除了

>>> b = B() 
>>> b.a = A() 
>>> b.a.attr1 = 'foo' 
>>> b.a.attr2 = 'bar' 

+6

爲什麼不把'self.a = A()'放入'B .__ init__'方法? – Maxim

+0

我應該提到...我不能這樣做,因爲我將無條件地在'__init__'(潛在地)中實例化的許多類都不會被使用。此外,A()中的某些代碼可能在'__init__'時激發,我不一定會做好準備。謝謝。 –

回答

2

你不得不無論是在B__init__創建a,使用__getattr__ hook動態創建a,或使用property

__init__方法:

class B(object): 
    def __init__(self): 
     self.a = A() 

__getattr__方法:

class B(object): 
    def __getattr__(self, attr): 
     if attr == 'a': 
      self.a = A() 
      return self.a 
     raise AttributeError(attr) 

物業的做法:

class B(object): 
    _a = None 

    @property 
    def a(self): 
     if self._a is None: 
      self._a = A() 
     return self._a 

當然,財產和__getattr__方法不噸o將A()實例存儲在self上,它可以僅從其他位置返回預先存在的A()實例。

+0

哈!你的'__getattr__'方法完全符合我的要求。我不會考慮使用'__GETattr__',因爲我使用'baattr1 ='foo'''__init__'來設置屬性不是我的選擇,因爲我不想實例化一堆類我不會使用。我應該提到這一點。謝謝。 –

0
class A(object): 
    pass 

class B(object): 
    def __init__(self): 
     self.a = A() 

b = B() 
b.a.attr1 = 'foo' 
b.a.attr2 = 'bar'