Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding an inherited property setter

I have a class called Node that has an importance setter and getter, below:

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

Later on, I have a class Theorem that inherits from Node. The only difference between a Theorem and a Node, as far as importance is concerned, is that a Theorem must have an importance of at least 3.

How can a Theorem inherit the importance setter, but add on the additional constraint that importance >= 3?

I tried to do it this way:

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
like image 975
mareoraft Avatar asked Aug 09 '15 21:08

mareoraft


People also ask

Can you override property in Python?

If you want to override a property in an arbitrary subclass, you can use a recipe like this. Note if you want deleter in addition to setter, then the decorator for the deleter must be @foo. deleter , not @A. foo.

Are getters and setters inherited?

They don't inherit private variables. This is simply not accurate. Both methods and variables (fields) have visibility restrictions. The subclass can always access (see) protected and public and may (if in same package) access default scoped.

What is property getters and setters?

What are Getters and Setters? Getters: These are the methods used in Object-Oriented Programming (OOPS) which helps to access the private attributes from a class. Setters: These are the methods used in OOPS feature which helps to set the value to private attributes in a class.


1 Answers

You can refer to the existing property directly through the Node class, and use the property's setter method to create a new property from it:

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)

This will create a new property into Theorem class that uses the getter method from Node.importance but replaces the setter method with a different one. That's how properties in general work: calling a property's setter returns a new property with a custom setter, which usually just replaces the old property.

You can learn more about how properties work by reading this answer (and the question too).

like image 60
Markus Meskanen Avatar answered Sep 24 '22 16:09

Markus Meskanen