2015-07-11 55 views
2

我想要繼承一個python類,並用@property函數覆蓋常規屬性。問題在於我無法修改父類,並且子類的api需要看起來與父類相同(但行爲不同)。 (我的問題是從this one其中父類也使用@property方法來訪問基礎屬性不同。)用@property覆蓋基類屬性

最簡單的可能的例子是

# assume this class can't be overwritten 
class Parent(object): 
    def __init__(self, a): 
     self.attr = a 

# how do I make this work? 
class Child(Parent): 
    def __init__(self, a): 
     super(Child, self).__init__(a) 

    # overwrite access to attr with a function 
    @property 
    def attr(self): 
     return super(Child, self).attr**2 

c = Child(4) 
print c.attr # should be 16 

這產生了錯誤時的父init方法被調用。

<ipython-input-15-356fb0400868> in __init__(self, a) 
     2 class Parent(object): 
     3  def __init__(self, a): 
----> 4   self.attr = a 
     5 
     6 # how do I make this work? 

AttributeError: can't set attribute 

希望很清楚我想要做什麼以及爲什麼。但我無法弄清楚如何。

+0

你需要寫你的屬性的設置,以及固定的。你有沒有閱讀[文檔](https://docs.python.org/2/library/functions.html#property)屬性?然而,我不認爲你正在嘗試的是什麼會起作用,因爲'self.attr'存儲在實例中,而不是類,所以按照你似乎正在嘗試的方式使用'super'將無濟於事。 – BrenBarn

回答

1

這是很容易通過添加一個setter方法

class Child(Parent): 
    def __init__(self, a): 
     self._attr = None 
     super(Child, self).__init__(a) 

    # overwrite access to a with a function 
    @property 
    def attr(self): 
     return self._attr**2 

    @attr.setter 
    def attr(self, value): 
     self._attr = value