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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With