In python, it is the duck type that is common used, rather that manipulate the subclass through the base classes is marginal.
however, it does not mean that you cannot use basec class and the abstract class. Here in this post, we are going to discuss how we create base class and how to use abstractmethod or abstractproperty decorators.
First, let's see how we can create base clases relationship with the .register method to register a user custome class to some other class.
from collections import MutableSequence
class TypedList:
def __init__(self, example_element, initial_list = []):
self.type = type(example_element)
if not isinstance(initial_list, list):
raise TypeError("Second argument of TypeList must be a list")
for elem in initial_list:
self.__check(elem)
self.elements = initial_list[:]
def __check(self, x):
if not isinstance(x, self.type):
raise TypeError("Attempt to add an element of incorrect type to a typed list")
def __setitem__(self, i , element):
self.elements[i] = element
def __getitem__(self, i):
return self.elements[i]
from abc import ABCMeta
class MyABC(metaclass = ABCMeta):
pass
if __name__ == '__main__':
from collections import MutableSequence
is_sequence = issubclass(TypedList, MutableSequence)
print("is_sequence is ", is_sequence)
MutableSequence.register(TypedList) # register a type to a base class will make the calling class the based class to the class in the parameter list
is_sequence = issubclass(TypedList, MutableSequence)
print("issubclass(TypedList, MutableSequence)", is_sequence)
# ABC.register(list)
MyABC.register(list)
is_instance = isinstance([1,2,3], MyABC)
print("is_instance is true", is_instance)
The key is here is the ABCMeta class to use as the metaclass to the register some other class as the base class (not necessary does the two has inheritance relationship). Also, some built-in classes has the .register method to accept classes as its subclasses.
now, let's see how we can use the @abstractmethod and @abstractproperty to create abstract base class, with abstract base class, you cannot create its instance unless you impl the abstract proeprty or method in its subclass.
from abc import ABCMeta, abstractmethod, abstractproperty
class MyABC(metaclass = ABCMeta):
def __init__(self):
self.__x = 0
@abstractmethod
def overrideme(self):
print("MyABC.overrideme()")
@abstractproperty
def readx(self):
return self.__x
def getx(self):
return self.__x
def setx(self, x):
self.__x = x
x = abstractproperty(getx, setx)
# create concrete class
class SecondABC(MyABC):
def __init__(self):
super().__init__()
self.__x = 0
def overrideme(self):
super().overrideme() # it is common that you call the base classes's override method
print("SecondABC.overrideme()")
#@property
def readx(self):
return super().readx()
def getx(self):
return super().getx()
def setx(self, x ):
super().setx(x)
x = property(getx, setx)
if __name__ == '__main__':
try:
my_abc = MyABC()
except TypeError as e:
pass
my_secondAbc = SecondABC()
my_secondAbc.overrideme()
x = my_secondAbc.getx()
print("*** ", x)