2016-06-10 27 views
0

哪裏我現在看起來是這樣的:在子類中重寫父類中的字段財產

class A(object): 
    def __init__(self, val): 
     self.x=val 
     self.y=42 
     # other fields 

class B(object): 
    def __init__(self): 
     self.a=22 
     # other fields 

class C(A,B): 
    def __init__(self, val): 
     super(C,self).__init__(val) 
    @property 
    def x(self): 
     # if A.x is None return a value that I can compute from A.y and B.a 
     # if A.x is not None return it 
    @x.setter 
    def x(self, val): 
     # set the field value 

有時候,我只是想爲x手動設定的假定值,在這種情況下,我只想用一個A。在其他情況下,我想要使用更復雜的方法,其中包含根據組織爲B的信息計算A.x的值。這個代碼的想法是創建一個C類,它看起來像A(根據x字段),但不需要手動設置該字段值,而只是派生出來。

我想不通的是如何讓C.x屬性以合理的方式影響A.x字段。

+0

你是什麼意思*做 「一個明智的方式」 *?你能否給出你試圖用這個做什麼,你期望什麼以及發生了什麼? – jonrsharpe

回答

2

A.__init__方法的行self.x = val只會調用你的C.x二傳手。你已經在這裏處理了一切。您在此處處理每個實例屬性,而不是由子類繼承的類上的屬性。

您只需要在設置器中設置不同的屬性以表示x值。你能說出它_x,例如:

class C(A, B): 
    _x = None 

    @property 
    def x(self): 
     if self._x is not None: 
      return self._x 
     return self.a + self.y 

    @x.setter 
    def x(self, val): 
     self._x = val 

需要注意的是,如果所有C.__init__所做的就是調用super().__init__,你不需要它。不過,你需要確保至少A.__init__()在繼承結構中扮演着角色;在更多的呼叫添加到super().__init__()

class A(object): 
    def __init__(self, val, *args, **kwargs): 
     super(A, self).__init__(*args, **kwargs) 
     self.x = val 
     self.y = 42 

class B(object): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(*args, **kwargs) 
     self.a = 22 

使用*args**kwargs允許這些方法來傳遞任何額外的參數層次結構中的其他類。

演示,使用上述類:

>>> c = C(None) 
>>> c.x 
64 
>>> c.x = 15 
>>> c.x 
15