2015-05-22 202 views
2

我GOOGLE了,發揮了一段時間,但沒有結果試圖做這樣的事情:Python類屬性和子類

class A(object): 
    cl_att = 'I am an A class attribute' 

class B(A): 
    cl_att += ' modified for B type' 

class C(A): 
    cl_att += ' modified for C type' 


instA = A() 
print insAt.cl_att 
>>> I am an A class attribute 

instB = B() 
print instB.cl_att 
>>> I am an A class attribute modified for B type 

instC = C() 
print instC.cl_att 
>>> I am an A class attribute modified for C type 

print instA.cl_att 
>>> I am an A class attribute 

總而言之一句話我希望能夠「使用,然後覆蓋」一我的父類的類屬性。

回答

1

假設你只有一個父類,你可以使用在回答最後在你的子類中定義的inherit_and_append裝飾,以獲得期望的結果,就像這樣:

class A(object): 
    cl_att = 'I am an A class attribute' 

@inherit_and_append('cl_att') 
class B(A): 
    cl_att = ' modified for B type' 

@inherit_and_append('cl_att') 
class C(A): 
    cl_att = ' modified for C type' 

如果有更高級的要求或條件,您可以進一步擴展裝飾器。

class inherit_and_append(object): 
    def __init__(self, *attrs): 
     super(inherit_and_append, self).__init__() 

     self._attrs = attrs 

    def __call__(self, klass): 
     parent = klass.__bases__[0] # Assuming you have a single parent class 
     for attr in self._attrs: 
      if not hasattr(parent, attr): 
       raise AttributeError("'{}' class has no '{}' attribute".format(parent.__name__, attr)) 

      parent_value = getattr(parent, attr) 
      klass_value = getattr(klass, attr) 
      setattr(klass, attr, parent_value + klass_value) 

     return klass 
7

參考父類的屬性,並連接到它:

class A(object): 
    cl_att = 'I am an A class attribute' 

class B(A): 
    cl_att = A.cl_att + ' modified for B type' 

class C(A): 
    cl_att = A.cl_att + ' modified for C type' 

類機構執行很像功能,與形成類屬性的本地名稱。 cl_att不存在於新的'函數'中,用於創建BC的實體,因此您需要直接引用基類上的屬性。

演示:

>>> class A(object): 
...  cl_att = 'I am an A class attribute' 
... 
>>> class B(A): 
...  cl_att = A.cl_att + ' modified for B type' 
... 
>>> class C(A): 
...  cl_att = A.cl_att + ' modified for C type' 
... 
>>> A.cl_att 
'I am an A class attribute' 
>>> B.cl_att 
'I am an A class attribute modified for B type' 
>>> C.cl_att 
'I am an A class attribute modified for C type'