在子类中使用属性覆盖父类中的字段

3

我现在的情况是这样的:

class A(object):
    def __init__(self, val):
        self.x=val
        self.y=42
        # other fields

class B(object):
    def __init__(self):
        self.a=22
        # other fields

class C(A,B):
    def __init__(self, val):
        super(C,self).__init__(val)
    @property
    def x(self):
        # if A.x is None return a value that I can compute from A.y and B.a
        # if A.x is not None return it
    @x.setter
    def x(self, val):
        # set the field value

有时我只想手动设置x的假设值,这种情况下我会使用A。在其他情况下,我想使用更复杂的方法,涉及计算基于组织为B的信息的A.x值。这段代码的思想是创建一个C类,它看起来像一个A(关于x字段),但不需要手动设置该字段值,而是直接从派生。 我无法弄清楚如何以明智的方式使C.x属性遮盖A.x字段。

你所说的“以明智的方式”是什么意思?你能提供一个 [mcve],说明你尝试过什么,期望发生什么,实际上又发生了什么吗? - jonrsharpe
1个回答

4
在A.__init__方法中的self.x = val这一行代码将会简单地调用你的C.x setter。你已经在这里处理了所有事情。你正在处理每个实例的属性,而不是被子类继承的类属性。
你需要做的就是在setter中设置一个不同的属性来表示x的值。例如,你可以将其命名为_x:
class C(A, B):
    _x = None

    @property
    def x(self):
        if self._x is not None:
            return self._x
        return self.a + self.y

    @x.setter
    def x(self, val):
        self._x = val

请注意,如果C.__init__的全部作用只是调用super().__init__,则根本不需要它。但是,您确实需要确保至少A.__init__()在继承结构中起作用;请添加更多对super().__init__()的调用。
class A(object):
    def __init__(self, val, *args, **kwargs):
        super(A, self).__init__(*args, **kwargs)
        self.x = val
        self.y = 42

class B(object):
    def __init__(self, *args, **kwargs):
        super(B, self).__init__(*args, **kwargs)
        self.a = 22

使用*args**kwargs允许这些方法将任何额外的参数传递给继承层次结构中的其他类。

演示,使用上述类:

>>> c = C(None)
>>> c.x
64
>>> c.x = 15
>>> c.x
15

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接