2013-05-21 46 views
4

我有一個使用領域的基礎類:如何用派生類中的屬性重寫基類中的字段?

class Base(object): 
    def __init__(self, member): 
     self.member = member 

而且派生類中,就是想推動這一個屬性,並添加一些行爲:

class Derived(Base): 
    @property 
    def member(self): 
     return super(Derived, self).member 

    @member.setter 
    def member(self, value): 
     print "intercepting setter" 
     super(Derived, self).member = value 

然而,這並未」 t正確地委託給基類:

>>> d = Derived(0) 
intercepting setter 

Traceback (most recent call last): 
    File "<pyshell#8>", line 1, in <module> 
    d = Derived(0) 
    File "<pyshell#3>", line 3, in __init__ 
    self.member = 2 
    File "<pyshell#6>", line 9, in member 
    super(Derived, self).member = value 
AttributeError: 'super' object has no attribute 'member' 

我應該怎麼做?

回答

2

您正試圖訪問超級的member,就好像它是類屬性一樣。試着用:

class Derived(Base): 
    @property 
    def member(self): 
     print "intercepting getter" 
     return self._member 

    @member.setter 
    def member(self, value): 
     print "intercepting setter" 
     self._member = value 
+1

我剛剛明白你的答案就是我在答案中的結果。 – Alfe

+0

_「好像它是一個類屬性」_ - 不會顯示爲'super(Derived).member'? – Eric

+0

不,使用'super'不會讓你訪問'Base'的一個假設的'member'屬性(你需要一個綁定的超類對象,提供一個像這樣的實例:'super(Derived,self) .member')。無論如何,在你的代碼中,'member'是構造函數初始化的一個**實例屬性**,'super'用於從基類訪問東西,而不是來自類實例的東西。 – Chewie

1

我認爲促進到性能的元件是這樣做的正確方法。這就像在基礎中有一個int成員,並將其更改爲派生類中的方法。或者像擁有一個普通的方法並將其更改爲繼承者中的靜態或類方法。我想這只是打破了這個概念。

你有幾個選擇來解決這個問題。

一,如何引入一個不同的(類似)名稱的屬性,然後繼承所有訪問的繼承原來的名稱?這將是非常簡單的,不會破壞從基類繼承的任何東西。但是它也不允許攔截對原始成員的訪問(在基類中或者在任何情況下)。

二,完全替換繼承的成員。這只是意味着將值存儲在不同的成員中,並完全從頭開始創建屬性。後來然後讓它訪問原來的店:

class Base(object): 

    def __init__(self, member): 
     self.member = member 

    def baseAccess(self): 
     return self.member 

class Derived(Base): 
    @property 
    def member(self): 
     print "getter", 
     return self.memberStore 

    @member.setter 
    def member(self, value): 
     print "setter", 
     self.memberStore = value 

b = Base(24) 
print "Base(24)" 
print "b.member", b.member 
print "b.baseAccess()", b.baseAccess() 
d = Derived(23) 
print "Derived(23)" 
print "d.member", d.member 
print "d.baseAccess()", d.baseAccess() 

b.member = 43 
print "b.member = 43" 
print "b.member", b.member 
print "b.baseAccess()", b.baseAccess() 
d.member = 42 
print "d.member = 42" 
print "d.member", d.member 
print "d.baseAccess()", d.baseAccess() 

這是輸出:

Base(24) 
b.member 24 
b.baseAccess() 24 
setter getter Derived(23) 
d.member getter 23 
d.baseAccess() getter 23 
b.member = 43 
b.member 43 
b.baseAccess() 43 
setter d.member = 42 
d.member getter 42 
d.baseAccess() getter 42 

因此,所有的攔截器適當考慮。

+1

當然'self.memberStore = self.member'是一個沒有操作,因爲'self.member'返回' self.memberStore'? – Eric

+0

你是對的!該行不是必需的。我刪除它。然後整個'__init __()'不再是必需的。也刪除它。 – Alfe

+0

另外,'.baseAccess()'似乎在做衍生訪問,因爲它觸發了攔截器 – Eric

相關問題