2013-05-21 45 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

相关问题