Reputation: 427
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! ;)
Upvotes: 1
Views: 389
Reputation: 6368
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.
Upvotes: 1