I would like to define an abstract method which from my base class through a second inheritance.
Since I can imagine that my question or even this sentence is confusing here is an example from what I am trying to do:
Imagine the following BaseClass containing 2 abstract methods: process & validation
class BaseClass(ABC):
"""
Base class for all services
"""
def __init__(self) -> None:
pass
@abstractmethod
def validate_input(self, payload: dict) -> None:
"""
validates the payload
"""
pass
@abstractmethod
def process(self, payload: dict) -> dict:
"""
processes the payload
"""
pass
As you can tell there are 2 methods in the BaseClass that need to be defined by the processes. I now want to define the process method in the Process1 class which will inherit from the BaseClass. However I also need to define the validate_input method, which can be the same for different processes. Therefore I thought of solving this using Multiple Inheritance. In my case I would like to create a second BaseValidation1 Class that contains a certain valdidation method, for example to check if there is key in the payload.
class Validation1(ABC):
"""
Validates if the payload is valid given a certained method e.g. if payload contains a certain key
"""
def validate_input(self, payload_dict: typing.Dict[str, typing.Any]) -> None:
"""
check if dict contains a certain key
"""
if not payload_dict:
raise ValidationException("payload is empty")
if not payload_dict.get("key"):
raise ValidationException("payload does not contain key")
So now I would like to inherit from both to define my Process1.
class Process1(BaseClass,Validation1):
"""
Base class for processing the payload
"""
def process(self, payload: typing.Dict) -> typing.Dict:
"""
Process the payload
"""
processed_payload = payload
return processed_payload
I am however super unsure if my method is even the best way to solve this problem. Furthermore Pylint already show the following warning:
E0110: Abstract class 'Process1' with abstract methods instantiated (abstract-class-instantiated)
Appreciate any solution.
CodePudding user response:
Your example works, if you reverse the order of your base classes:
class Process1(Validation1, BaseClass):
...
The reason has to do with python's method resolution order: The way you defined the parent classes of Process1
causes the python interpreter to "find" BaseClass.validate()
when you invoke Process1.validate()
, which is abstract.
I would further remove the ABC parent from Validation1
, as I consider that class a Mixin. Here is a fullly working minimal example:
from abc import ABC, abstractmethod
class BaseClass(ABC):
def __init__(self):
pass
@abstractmethod
def validate(self):
pass
@abstractmethod
def process(self):
pass
class ValidationMixin:
def validate(self):
pass
class Processor(ValidationMixin, BaseClass):
def process(self):
pass