I would like to know if it is possible to use multiple inheritance with abstract base class in python. It seems like it should be possible but can't find a statement one way or the other.
The basic ABC example:
from abc import ABC, abstractmethod
class BaseABC(ABC):
@abstractmethod
def hello(self):
pass
class Child(BaseABC):
pass
child = Child()
This will fail due to "hello" not being implemented in "Child".
What I would like is to know how to combine ABC with multiple inheritance. I would like to make either the "BaseABC" or "Child" to inherit also from some other separate class. Explicitly:
from abc import ABC, abstractmethod
class BaseABC(ABC, dict):
@abstractmethod
def hello(self):
pass
class Child(BaseABC):
pass
child = Child()
This does not fail in the way expected as the first case does. Also:
from abc import ABC, abstractmethod
class BaseABC(ABC):
@abstractmethod
def hello(self):
pass
class Child(BaseABC, dict):
pass
child = Child()
This does not fail either. How can I require "Child" to implement "hello"?
The issue is with inheriting from a dict, which is probably better explained by these guys:
From my understanding, the built-in list, dict, and set types have in-lined a lot of code for performance. Essentially, they’ve copy-pasted the same code between many different functions to avoid extra function calls and make things a tiny bit faster.
I haven’t found a reference online that explains why this decision was made and what the consequences of the alternatives to this choice were. But I mostly trust that this was done for my benefit as a Python developer. If dict and list weren’t faster this way, why would the core developers have chosen this odd implementation?
It happens, because Python built-in dict is implemented on C and its methods are independent of one another. It is done for performance, I guess.
So depending on little what you want to do with your subclassed dict you could go with MutableMapping as suggested in https://stackoverflow.com/a/3387975/14536215 or with UserDict (which is a subclass of MutableMapping) such as:
from abc import ABC, abstractmethod
from collections import UserDict
class BaseABC(ABC):
@abstractmethod
def hello(self):
pass
class Child(BaseABC, UserDict):
pass
child = Child()