This is an extension to this question and raises a problem, which you, my fellow StackOverflowers, will hopefully be able to help me with. From the referenced question, consider the final code sample:
class A(object):
def __init__(self):
print "entering A"
print "leaving A"
class B(object):
def __init__(self):
print "entering B"
super(B, self).__init__()
print "leaving B"
class C(A,B):
def __init__(self):
print "entering c"
super(C, self).__init__()
print "leaving c"
As noted by the poster, when initialising C, the __init__
for B is never called. On considering Raymond Hettinger's post, the code for class A
should be modified to also call super().__init__()
:
class A(object):
def __init__(self):
print "entering A"
super(A, self).__init__()
print "leaving A"
We're all good so far. However, what if our class' __init__
functions accept arguments? Let's assume that all the __init__
functions accept a single argument and for consistency, we'll simply call it foo
, the code is now:
class A(object):
def __init__(self, foo):
print "entering A"
super(A, self).__init__(foo)
print "leaving A"
class B(object):
def __init__(self, foo):
print "entering B"
super(B, self).__init__(foo)
print "leaving B"
class C(A,B):
def __init__(self, foo):
print "entering c"
super(C, self).__init__(foo)
print "leaving c"
Here we hit a snag. When initialising any of the classes A, B or C, we eventually call object.__init__
with a single argument, foo
, which errors with TypeError: object.__init__() takes no parameters
. However, to remove one of the super().__init__
functions would mean the classes are no longer cooperative in the case of multiple inheritance.
After all that, my question is how does one get around this problem? It appears that multiple inheritance is broken in anything but cases where no arguments are passed to the __init__
functions.
UPDATE:
Rob in the comments suggests stripping keyword arguments (referenced in Raymond H's post). This actually works very well in the case of multiple inheritance until your change you code. If one of your functions no longer uses one of the keyword arguments and ceases to strip it without modifying the calling function, You will still receive the TypeError noted above. As such, this seems like a fragile solution for large projects.
In multiple inheritances, the methods are executed based on the order specified while inheriting the classes.
In Ruby, single class inheritance is supported, which means that one class can inherit from the other class, but it can't inherit from two super classes. In order to achieve multiple inheritance, Ruby provides something called mixins that one can make use of.
Ruby supports only single class inheritance, it does not support multiple class inheritance but it supports mixins.
Admittedly, this solution may not be the most pythonic or ideal, but creating a wrapper class for object like so allows you to pass arguments around each __init__
in the inheritance:
class Object(object):
def __init__(self,*args,**kwargs):
super(Object,self).__init__()
class A(Object):
def __init__(self,*args,**kwargs):
super(A,self).__init__(*args,**kwargs)
class B(Object):
def __init__(self,*args,**kwargs):
super(B,self).__init__(*args,**kwargs)
class C(A,B):
def __init__(self,*args,**kwargs):
super(C,self).__init__(*args,**kwargs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With