【问题标题】:Override a field in parent class with property in child class用子类中的属性覆盖父类中的字段
【发布时间】:2016-10-11 22:34:57
【问题描述】:

我现在的位置是这样的:

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 字段。

【问题讨论】:

  • 你是什么意思“以一种明智的方式”?您能否提供minimal reproducible example 说明您尝试对此进行的操作、您的预期以及发生了什么?

标签: python python-2.7 inheritance properties


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    相关资源
    最近更新 更多