Reputation: 301
As explained in How does Python's super() work with multiple inheritance?, super
can be used in multiple inheritance as well, as it will look for the attribute in both parents. But what attribute? The subclass already includes a super
(if you look at the code below). How do I specify the attribute I want? I want Error
's constructor.
class Error(object):
def __init__(self, values):
self.values = values
class AddDialog(sized_controls.SizedDialog, Error):
def __init__(self, *args, **kwargs):
Error.__init__(self, *args)
super(AddDialog, self).__init__(*args, **kwargs)
Upvotes: 0
Views: 52
Reputation: 85462
It is as easy as just trying it out:
class Error(object):
def __init__(self, values):
self.values = values
print('Error')
class SizedDialog(object):
def __init__(self, values):
self.values = values
print('SizedDialog')
class AddDialog(SizedDialog, Error):
def __init__(self, *args, **kwargs):
print('AddDialog')
Error.__init__(self, *args)
super(AddDialog, self).__init__(*args, **kwargs)
Now, super()
is nothing else but going along the method resolution order (MRO) which you can get with mro()
:
>>> AddDialog.mro()
[__main__.AddDialog, __main__.SizedDialog, __main__.Error, object]
So, in your case you call the __init__()
of Error
explicitly first. Then super()
will, in this specific case, find the __init__()
of SizedDialog
because it comes before Error
in the MRO.
>>> a = AddDialog(10)
AddDialog
Error
SizedDialog
If you only use super()
(no call to __init__()
of Error
), you get only the __init__()
of SizedDialog
:
class AddDialog(SizedDialog, Error):
def __init__(self, *args, **kwargs):
print('AddDialog')
super(AddDialog, self).__init__(*args, **kwargs)
>>> a = AddDialog(10)
AddDialog
SizedDialog
Finally, if you only call the __init__()
of Error
, it is the only __init__()
that is called.
class AddDialog(SizedDialog, Error):
def __init__(self, *args, **kwargs):
print('AddDialog')
Error.__init__(self, *args)
>>> a = AddDialog(10)
AddDialog
Error
So your question:
But what attribute?
has the answer:
The one you call.
It does not matter if you hard-wire the class, as done with Error
, or let super()
find the appropriate parent class, i.e. the next one in the MRO.
The only difference is that super()
might call the __init__()
of the grandparent class if the parent class does not have an __init__()
.
But this is the intended behavior of super()
.
Upvotes: 1