Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python abstract property setter with concrete getter

Tags:

python

is it possible to use abc.abstractproperty to create a concrete getter but make the setter abstract so its different for each of the inheriting classes. I handle the setting of val different for each subclass.

eg.

@abstractproperty
def val(self):
    return self._val

@val.setter
def val(self, x):
    pass
like image 408
jack sexton Avatar asked Feb 11 '16 16:02

jack sexton


People also ask

Can we use getters and setters in abstract class?

You can do everything in an abstract class that you can do in a normal class except creating a new object only by using a constructor. This means that you can simply copy and paste the getters and setters from your subclass into your parent class.

Should I use getter and setter in Python?

Getters and Setters in python are often used when: We use getters & setters to add validation logic around getting and setting a value. To avoid direct access of a class field i.e. private variables cannot be accessed directly or modified by external user.

Is @property a getter?

@property is used to get the value of a private attribute without using any getter methods. We have to put a line @property in front of the method where we return the private variable. To set the value of the private variable, we use @method_name.


1 Answers

You'll need a little bit of indirection. Define the setter as you normally would, but have it call an abstract method that does the actual work. Then each child class will need to provide a definition of that method. For example,

class Base(object):
    __metaclass__ = abc.ABCMeta

    def __init__(self):
        self._val = 3

    @property
    def val(self):
        return self._val

    @val.setter
    def val(self, x):
        self._val_setter(x)

    @abc.abstractmethod
    def _val_setter(self, x):
        pass


class Child(Base):

    def _val_setter(self, x):
        self._val = 2*x

Then

>>> c = Child()
>>> print c.val
3
>>> c.val = 9
>>> print c.val
18
like image 84
chepner Avatar answered Sep 22 '22 13:09

chepner