如何使用派生类中的属性覆盖基类中的字段?

时间:2013-05-21 10:12:21

标签: python properties override

我有一个使用字段的基类:

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

但是,这不能正确委托给基类:

>>> 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 个答案:

答案 0 :(得分: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 :(得分:1)

我认为成员提升为属性是正确的做法。就像在基数中有一个int成员并将其更改为派生类中的方法一样。或者像使用普通方法并将其更改为继承器中的静态或类方法。我想这只是打破了这个概念。

您有几种方法可以解决此问题。

予。如何引入一个不同(相似)名称的属性,然后传递对继承原始名称的所有访问权限?这将非常简单,不会破坏从基类继承的任何内容。但它也不允许拦截对原始成员的访问(在基类或者任何时候完成)。

II。完全替换继承的成员。这只是意味着将值存储在不同的成员中并从头开始创建属性。之后再让它访问原始商店:

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

所以所有的拦截器都得到了适当的考虑。