Reputation: 12697
I have a structure like
class A:
def __init__(self, x):
self.a=x
class B(A):
def __init__(self, x):
self.b=x
class C(A):
def __init__(self, x):
self.c=x
class D(B,C):
def __init__(self, x):
self.d=x
Now I'd like to extend the __init__
s such that both B
and C
will call A
, too (B and C can be used as stand-alone classes). Moreover D
should call A, B and C (D combines features from B and C but still needs to run all initializations). All __init__
take the same parameter. Obviously A should be called only once.
Do you see an easy way to do that?
Upvotes: 2
Views: 164
Reputation: 309949
Use super
. As far as I'm aware, this is it's purpose ...
First, some proposed reading:
Next, an example:
class A(object):
def __init__(self, x):
print "Called A"
self.a=x
class B(A):
def __init__(self, x):
print "Called B"
super(B,self).__init__(x)
self.b=x
class C(A):
def __init__(self, x):
print "Called C"
super(C,self).__init__(x)
self.c=x
class D(B,C):
def __init__(self, x):
print "Called D"
super(D,self).__init__(x)
self.d=x
foo = D(10)
As stated in the comments, you often see methods which use super defined to accept any number of positional and keyword arguments:
def mymethod(self,*args,**kwargs):
super(thisclass,self).method(*args,**kwargs)
...
As that allows super
to pass the necessary/unnecessary arguments on to other objects in the inheritance chain. Those methods can then decide which arguments they need and ignore the rest (passing them on to the next super
of course)
Finally, to complete this discussion, we need to discuss python2.x vs. python3.x. In python2.x, all of your classes must be new style (they need to inherit from object
eventually). In python3.x, this is automatic. And in python3.x, you can omit the arguments to super
.
super().__init__(*args,**kwargs)
However, I prefer the python2.x style as it works for both python2.x and python3.x and I'm always left wondering how super()
(python3.x style) knows what object to pass to the underlying methods as self
. It seems a lot more magical then even the python2.x version to me...
Upvotes: 6
Reputation: 10585
Using super
class D(B, C):
def __init__(self, *args, **kwargs):
super(D, self).__init__(*args, **kwargs)
self.d = args[0]
Some explanation about super here and a related question
In Python 2 you should also inherit from object
to use new style classes, and add super
to your other classes too.
Upvotes: 2