5

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

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'

我应该怎么做?

4

2 回答 2

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
于 2013-05-21T10:54:47.593 回答
2

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

你有几个选项来解决这个问题。

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

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

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

因此,所有拦截器都得到了适当的考虑。

于 2013-05-21T11:14:38.837 回答