Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 重写继承的属性设置程序_Python_Oop_Python 3.x_Inheritance - Fatal编程技术网

Python 重写继承的属性设置程序

Python 重写继承的属性设置程序,python,oop,python-3.x,inheritance,Python,Oop,Python 3.x,Inheritance,我有一个名为Node的类,它具有重要性setter和getter,如下所示: class Node: @property def importance(self): return self._importance @importance.setter def importance(self, new_importance): if new_importance is not None: new_impor

我有一个名为
Node
的类,它具有
重要性
setter和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

您可以通过
节点
类直接引用现有属性,并使用属性的
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)
这将在
定理
类中创建一个新属性,该类使用
节点的getter方法。重要性
但用另一个方法替换setter方法。 这就是属性在一般情况下的工作方式:调用属性的
setter
返回一个带有自定义setter的新属性,自定义setter通常只替换旧属性


通过阅读(还有这个问题),您可以了解更多关于属性如何工作的信息。

一种方法是使用
节点
getter在
定理
上实现一个新属性,提供一个新的setter方法,并在其中显式调用
节点
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
完成


根据,您可以:

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计划的(将于年到期)。

对于更广泛的问题,这里有一个完全不同的解决方案,其中涉及的问题要少得多:

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!
类节点:
最小重要性=1
最大重要性=10
@财产
def重要性(自我):
回归自我
@二传手
定义重要性(自我、新的重要性):
如果新的_重要性不是无:
新的重要性=检查类型和清洁(新的重要性,整数)
断言(新的重要性>=self.MIN重要性和

new_importance
TypeError:setter()只接受一个参数(给定2个)
。你是说
fset
?@jornsharpe Ups,现在试试:PYep,比我的好得多,也更整洁!@MarkusMeskanen所以写
@Node.importance.setter
上面的
重要性的定义与写
重要性=Node.importance.setter(importance)是一样的事情
下面是重要性的定义?@mareoraft事实上,所有的装饰程序都是这样工作的,
@
只是语法上的糖分。不要把
self.\uu class\uu
传给
super()
。当你从
定理
@Kevin中创建子类时,它会完全崩溃吗?快速测试表明它会到达
节点。重要性。fset
定理
子类实例。它是
超级(TheoremSubclass,TheoremSubclass)吗.importance
将返回您在最后一行中创建的对象。一旦调用
fset(),将产生无限递归
@Kevin您似乎是对的,我不明白为什么这不是第一次发生的!注意,您可以通过在
节点中设置class属性
MIN\u-IMPORTANCE
来完全不同地解决问题,即在
节点中设置
1
,在
定理中设置
3
。对于提出的具体问题示例。上述公认的答案是公认的答案,因为它解决了所提出的问题,并且与标题有关。不过,我感谢这一深思熟虑的答案。
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!