super() before multiple inheritance, especially for methods present on object can get a little confused . The general rule is that if you use super , then every class in the hierarchy should use super . A good way to handle this for __init__ is to make each method **kwargs and always use keyword arguments everywhere. By the time the call to object.__init__ all arguments must be popped up!
class Base1(object): def __init__(self, a, **kwargs): print "In Base 1", a super(Base1, self).__init__() class Base2(object): def __init__(self, **kwargs): print "In Base 2" super(Base2, self).__init__() class Child(Base1, Base2): def __init__(self, **kwargs): super(Child, self).__init__(a="Something for Base1")
Check out the related article to learn more about how it works and how to make it work for you!
Edit: risking answering two questions: "Why use super at all?"
We have super() for many of the same reasons that we have classes and inheritance, as a tool for modulating and abstracting our code. When working with an instance of a class, you do not need to know all the detailed information about how this class was implemented, you only need to know its methods and attributes, as well as how you should use this open interface for the class. In particular, you can be sure that changes to the class implementation cannot cause problems as a user of its instances.
The same argument applies when getting new types from base classes. You do not want or should not worry about how these base classes were implemented. Here's a concrete example of how not to use super, could go wrong. suppose you have:
class Foo(object): def frob(self): print "frobbign as a foo" class Bar(object): def frob(self): print "frobbign as a bar"
and you create a subclass:
class FooBar(Foo, Bar): def frob(self): Foo.frob(self) Bar.frob(self)
Everything is fine, but then you understand that when you start it, Foo really is a kind of Bar , so you change it
class Foo(Bar): def frob(self): print "frobbign as a foo" Bar.frob(self)
That everything is fine, except that in your derived class, FooBar.frob() calls Bar.frob() twice.
This is the exact problem super() solves, it protects you from calling superclass implementations more than once (when used as intended ...)