覆盖继承的属性setter

时间:2015-08-09 21:38:59

标签: python oop python-3.x inheritance

我有一个名为.outer-widediv{ background : color !important; position: relative; } .outer-widediv:after{ content: ""; display: block; height: 100%; } .outer-widediv:before{ content: ""; display: block; height: 100%; } 的课程,其中有一个Node setter和getter,如下所示:

importance

稍后,我有一个继承自class Node: @property def importance(self): return self._importance @importance.setter def importance(self, new_importance): if new_importance is not None: new_importance = check_type_and_clean(new_importance, int) assert new_importance >= 1 and new_importance <= 10 self._importance = new_importance 的课程Theorem。就Node而言,TheoremNode之间的唯一区别是,importance必须至少Theorem importance 1}}。

定理如何继承 3 setter,但添加importance的其他约束?

我试着这样做:

importance >= 3

3 个答案:

答案 0 :(得分:12)

您可以直接通过Node类引用现有属性,并使用属性的setter方法从中创建新属性:

class Theorem(Node):
    @Node.importance.setter
    def importance(self, new_importance):
        # You can change the order of these two lines:
        assert new_importance >= 3
        Node.importance.fset(self, new_importance)

这将在Theorem类中创建一个新属性,该属性使用Node.importance中的getter方法,但用不同的方法替换setter方法。 这就是一般工作中的属性:调用属性的setter返回一个带有自定义setter的新属性,该属性通常只是替换旧属性。

您可以通过阅读this answer(以及问题)了解有关物业如何运作的更多信息。

答案 1 :(得分:4)

执行此操作的一种方法是使用Theorem getter在Node上实现新属性,提供新的setter方法并在其中显式调用Node setter:

class Theorem(Node):

    def _set_importance(self, new):
        Node.importance.fset(self, new)
        assert self.importance >= 3

    importance = property(Node.importance.fget, _set_importance)

据我所知,super无法做到这一点。

this bug report,您可以这样做:

class Theorem(Node):

    def _set_importance(self, new):
        super(Theorem, Theorem).importance.fset(self, new)
        assert self.importance >= 3

    importance = property(Node.importance.fget, _set_importance)

然而,这显然有点尴尬;允许super()的补丁似乎是为Python 3.5安排的(在September 2015中到期)。

答案 2 :(得分:2)

对于更广泛的问题,这是一个完全不同的解决方案,而且不那么费力:

class Node:

    MIN_IMPORTANCE = 1
    MAX_IMPORTANCE = 10

    @property
    def importance(self):
        return self._importance

    @importance.setter
    def importance(self, new_importance):
        if new_importance is not None:
            new_importance = check_type_and_clean(new_importance, int)
            assert (new_importance >= self.MIN_IMPORTANCE and 
                    new_importance <= self.MAX_IMPORTANCE)
        self._importance = new_importance


class Theorem(Node):

    MIN_IMPORTANCE = 3

    # and that's all it takes!

在我看来,这表达了:

  

TheoremNode之间的唯一区别,就importance而言   我们担心,Theorem必须至少importance 3

比覆盖属性setter更清楚。

请注意,assert通常用于测试和调试,而不是作为一般程序流程的一部分,当然不适用于您希望可能发生的事情;见例如Best practice for Python Assert