Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Abstract Properties in Python

What's the best, most Pythonic, way to deal with abstract properties in Python? If I want to implement a base class which has a mixture of abstract properties, and concrete methods, I can do so similar to the following.

class BaseClass(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def property1(self):
        pass

    @abstractmethod
    def property2(self):
        pass

    @abstractmethod
    def property3(self):
        pass

    @abstractmethod
    def abstract_method(self):
        pass

    def concrete_method(self):
        return self.property1 + self.property2

However, when I then go to implement the inheriting class I need to implement each of those properties as getter method for a private property.

class Klass(BaseClass):
    def __init__(self, property1, property2, property3):
        self.__property1 = property1
        self.__property2 = property2
        self.__property3 = property3

    @property
    def property1(self):
        return self.__property1

    @property
    def property2(self):
        return self.__property2

    @property
    def property3(self):
        return self.__property3

Which seems both unnecessarily verbose, and makes the code more obscure than it needs to be.

I don't love the idea of implementing things concretely and raising a NotImplementedErrorif the inheriting class doesn't implement it's own version.

Is there a better way to do this?

like image 541
Gree Tree Python Avatar asked Jun 09 '26 11:06

Gree Tree Python


1 Answers

You are not required to implement properties as properties. All you need is for the name to exist on the class. So the following, using regular attributes, would work:

class Klass(BaseClass):
    property1 = None
    property2 = None
    property3 = None

    def __init__(self, property1, property2, property3):
        self.property1 = property1
        self.property2 = property2
        self.property3 = property3

    def abstract_method(self):
        # implementation for the abstract method

Note that there is a abstractproperty decorator that'd better document that you want to use those names as simple values, not methods to call:

class BaseClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def property1(self):
        pass

    @abstractproperty
    def property2(self):
        pass

    @abstractproperty
    def property3(self):
        pass

    @abstractmethod    
    def abstract_method(self):
        pass

    def concrete_method(self):
        return self.property1 + self.property2
like image 61
Martijn Pieters Avatar answered Jun 12 '26 03:06

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!