覆盖继承的属性setter

mar*_*aft 11 python oop inheritance python-3.x

我有一类叫做Node一个具有importancesetter和getter,如下:

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
Run Code Online (Sandbox Code Playgroud)

后来,我有一个Theorem继承自的类Node.就所涉及的而言,a Theorem和a 之间的唯一区别是必须具有至少一个.NodeimportanceTheoremimportance3

一个定理如何能继承importance二传手,但增加的附加约束importance >= 3

我试着这样做:

class Theorem(Node):

    @importance.setter
    def importance(self, new_importance):
        self.importance = new_importance # hoping this would use the super() setter
        assert self.importance >= 3
Run Code Online (Sandbox Code Playgroud)

Mar*_*nen 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)
Run Code Online (Sandbox Code Playgroud)

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

您可以通过阅读此答案(以及问题)了解有关属性如何工作的更多信息.

  • @mareoraft确实是*所有*装饰器的工作方式,“ @”只是语法糖。 (2认同)

jon*_*rpe 5

对于更广泛的问题,这是一个完全不同的解决方案,少了很多麻烦:

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!
Run Code Online (Sandbox Code Playgroud)

在我看来,这表达了:

就 a 而言, aTheorem和 a之间的唯一区别 是 a必须至少有一个of 。NodeimportanceTheoremimportance3

比重写属性设置器更清楚。


请注意,它assert通常用于测试和调试,而不是作为一般程序流程的一部分,当然也不是用于您期望可能发生的事情;请参阅例如Python Assert 的最佳实践