Home > Blockchain >  @abstractmethod given by a second class to inherit from (multiple inheritance with abstract methods)
@abstractmethod given by a second class to inherit from (multiple inheritance with abstract methods)

Time:12-03

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
  • Related