When inheriting from two objects like these
class Foo(object):
def __init__(self,a):
self.a=a
class Bar(object):
def __init__(self,b):
self.b=b
I would normally do something like this
class FooBar(Foo,Bar):
def __init__(self,a,b):
Foo.__init__(self,a)
Bar.__init__(self,b)
How does super know if I want to call both? and if so how will it know which argument to pass where. Or is it simply not possible to user super here?
Even if Foo and Bar take the same arguments can super deal with this?
Or should I not be trying to do this kind of this in the first place?
Using
super(),__init__()and multiple inheritance is a bit tricky.In the normal flow of things, every method calls
super(), with the classes that inherit only fromobjectdoing a little extra work to make sure that the method actually exists: it’ll look a bit like this:But when you try to do something similar on a method that
objectactually has, things get a little dicey;object.__init__doesn’t take arguments, so about the only safe way to use it is to callsuper().__init__()with no arguments, since that call might be handled byobject.__init__. But then it might not be handled byobject.__init__, and instead handled by a class elsewhere in the inheritance graph. Thus any class which defines__init__in a multiple inheritance class heirarchy must be prepared to be called with no arguments.one way of dealing with this is to never use arguments in
__init__(). Do minimal initialization, and rely on setting properties or using other means to configure the new object before use. That’s pretty unpleasant, though.Another way is to use only keyword arguments, something like
def __init__(self, **keywords):and always remove the arguments that apply to the given constructor. This is a hope based strategy, you hope that all of the keywords get consumed before control reachesobject.__init__.A third way is to define a superclass to all of the multiple-inheritable bases which itself defines
__init__in some useful way and does not callsuper().__init__(object.__init__is a no-op anyway). This means you can be sure that this method is always called last, and you can do whetever you like with your arguments.