1

I have a fundamental class called MetaFunction

class MetaFunction(metaclass=ABCMeta):

    def __init__(
            self,
            pickle_data: PickleData,
            eth_protocols: Protocols = (),
            spi_protocols: Protocols = ()
    )

Class AEB inherits from MetaFunction:

class AEB(MetaFunction):

    def __init__(
            self,
            pickle_data: PickleData,
            eth_protocols: Protocols = (),
            spi_protocols: Protocols = (),
    ):
                    super().__init__(
                pickle_data=pickle_data,
                eth_protocols=eth_protocols,
                spi_protocols=spi_protocols
            )

But there is also a second base class except MetaFunction called EventFinder:

class EventFinder:
    def __init__(self, pickle_filename, export_path):

The final child class that I want to create is AEBEventFinder:

class AEBEventFinder(AEB, EventFinder):
    def __init__(
            self,
            pickle_filename: str,
            export_path: str,
            pickle_data: PickleData,
            eth_protocols: Protocols = (),
            spi_protocols: Protocols = ()
    ):
        AEB.__init__(
            self,
            pickle_data=pickle_data,
            eth_protocols=eth_protocols,
            spi_protocols=spi_protocols,
        )
        EventFinder.__init__(
            self,
            pickle_filename=pickle_filename,
            export_path=export_path
        )

As you can see it inherits from both AEB and EventFinder classes. I solved it using the old approach. None of these worked for me: Calling parent class __init__ with multiple inheritance, what's the right way?

    super().__init__(
        pickle_data=pickle_data,
        eth_protocols=eth_protocols,
        spi_protocols=spi_protocols,
    )
    super(EventFinder, self).__init__(
        pickle_filename=pickle_filename,
        export_path=export_path
    )

According to the link above, I get the following error: TypeError: object.init() takes exactly one argument (the instance to initialize)

How can I solve it using the appropriate 'new' pythonic way?

SOLVED Added **kwargs to each parent class (MetaFunction, AEB, EventFinder) and it worked. No implicit super().init() call in each parent class is needed! ;)

1
  • Can you give us the full error message, including stack trace? Commented May 6, 2021 at 11:17

1 Answer 1

1

You should change your parent classes to accept all keyword arguments and just use the ones they recognize. And then you can use super as intended:

from abc import ABCMeta
PickleData = Protocols = object

class MetaFunction(metaclass=ABCMeta):
    def __init__(
        self,
        pickle_data: PickleData,
        eth_protocols: Protocols = (),
        spi_protocols: Protocols = (),
        **kwargs,
    ):
        super().__init__(
            pickle_data=pickle_data,
            eth_protocols=eth_protocols,
            spi_protocols=spi_protocols,
            **kwargs,
        )

        
class AEB(MetaFunction):

    def __init__(
        self,
        pickle_data: PickleData,
        eth_protocols: Protocols = (),
        spi_protocols: Protocols = (),
        **kwargs,
    ):
        super().__init__(
            pickle_data=pickle_data,
            eth_protocols=eth_protocols,
            spi_protocols=spi_protocols,
            **kwargs,
            )

        
class EventFinder:
    foo = 'foo'
    def __init__(self, pickle_filename, export_path, **kwargs):
        self.bar = 'bar'        

        
class AEBEventFinder(AEB, EventFinder):
    def __init__(self, my_own_argument, **kwargs):
        super().__init__(**kwargs)
        # do something with my_own_argument
        
mytest = AEBEventFinder(pickle_data=None, pickle_filename='fn', export_path='.', my_own_argument='blah')
assert mytest.foo == 'foo'
assert mytest.bar == 'bar'

If the parent classes are beyond your control and are uncooperative by not accepting arguments they don't recognize, you can write an adapter that wraps them.

Raymond Hettinger has given a great primer "Super considered super" at PyCon.

Sign up to request clarification or add additional context in comments.

3 Comments

It seems like it does not inherit any attributes from EventFinder class :/
@FilipSzczybura That must be a different problem. I've changed the example to show attributes work fine.
I solved it by removing super() call in each parent class. Addition of kwargs did the job

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.