In Python 3.6, Let's say I have an abstract class MyAbstractClass
from abc import ABC, abstractmethod
class MyAbstractClass(ABC):
@property
@abstractmethod
def myProperty(self):
pass
and a class MyInstantiatableClass inherit from it. So how do I write to the property myProperty on instantiation of an object from this class? I'd like to be able to both set and get myProperty. Below doesn't work.
from MyAbstractClass import MyAbstractClass
class MyInstantiatableClass(MyAbstractClass):
def __init__(self, desiredValueOfMyProperty):
????
@myProperty.setter
def myProperty(self, desiredValueOfMyProperty): # value coming from __init__
self._myProperty = desiredValueOfMyProperty
And a main function, say,
from MyInstantiatableClass import MyInstantiatableClass
def main():
MyInstantiatableClass(3) # 3 is the desiredValueOfMyProperty for this instantiation
MyInstantiatableClass(5) # 5 is the desiredValueOfMyProperty for this instantiation
It seems there's a discrepancy here; using @property along with @abstractmethod doesn't seem to enforce classes that inherit from your abc to need to define both setter and getter. Using this:
@property
@abstractmethod
def myProperty(self):
pass
@myProperty.setter
@abstractmethod
def myProperty(self):
pass
and then providing an implementation only for the getter in the class works and allows for instantiation:
@property
def myProperty(self):
return self._myProperty
This is due to the fact that only one name (myProperty) appears in the namespace of the ABC, when you override in the base class, you only need to define this one name.
There's a way around that enforces it. You can create separate abstract methods and pass them on to property directly:
class MyAbstractClass(ABC):
@abstractmethod
def getProperty(self):
pass
@abstractmethod
def setProperty(self, val):
pass
myAbstractProperty = property(getProperty, setProperty)
Providing an implementation for this abc now requires both getter and setter to have an implementation (both names that have been listed as abstractmethods in MyAbstractClass namespace need to have an implementation):
class MyInstantiatableClass(MyAbstractClass):
def getProperty(self):
return self._Property
def setProperty(self, val):
self._Property = val
myAbstractProperty = property(getProperty, setProperty)
Implementing them is exactly the same as any old property. There's no difference there.
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