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 from object
doing a little extra work to make sure that the method actually exists: it'll look a bit like this:
>>> class Foo(object):
... def frob(self, arg):
... print "Foo.frob"
... if hasattr(super(Foo, self), 'frob'):
... super(Foo, self).frob(arg)
...
>>> class Bar(object):
... def frob(self, arg):
... print "Bar.frob"
... if hasattr(super(Bar, self), 'frob'):
... super(Bar, self).frob(arg)
...
>>> class Baz(Foo, Bar):
... def frob(self, arg):
... print "Baz.frob"
... super(Baz, self).frob(arg)
...
>>> b = Baz()
>>> b.frob(1)
Baz.frob
Foo.frob
Bar.frob
>>>
But when you try to do something similar on a method that object
actually has, things get a little dicey; object.__init__
doesn't take arguments, so about the only safe way to use it is to call super().__init__()
with no arguments, since that call might be handled by object.__init__
. But then it might not be handled by object.__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 reaches object.__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 call super().__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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…