What is the semantics meaning of 'object'?

Ian Kelly ian.g.kelly at gmail.com
Sun Jun 23 13:08:56 EDT 2013


On Sun, Jun 23, 2013 at 10:49 AM, Roy Smith <roy at panix.com> wrote:
> One thing I've never understood about Python 2.x's multiple inheritance
> (mostly because I almost never use it) is how you do something like this:
>
> class Base1(object):
>    def __init__(self, foo):
>       self.foo = foo
>
> class Base2(object):
>    def __init__(self, bar):
>       self.bar = bar
>
> class Derived(Base1, Base2):
>    def __init__(self, foo, bar):
>       # now what???
>
> I need to call __init__() in both of my base classes.  I don't see how
> super() can do that for me.  I assume I would just do:
>
>    def __init__(self, foo, bar):
>       Base1.__init__(self, foo)
>       Base2.__init__(self, bar)
>
> am I missing something here?

Yes, you're missing that super() does not simply call the base class,
but rather the next class in the MRO for whatever the type of the
"self" argument is.  If you write the above as:

class Base1(object):
   def __init__(self, foo, **kwargs):
      super(Base1, self).__init__(**kwargs)

class Base2(object):
   def __init__(self, bar, **kwargs):
      super(Base2, self).__init__(**kwargs)

class Derived(Base1, Base2):
   def __init__(self, **kwargs):
      super(Derived, self).__init__(**kwargs)

And then you create an instance of Derived by calling
Derived(foo='foo', bar='bar') and trace the call chain, you find that
Derived.__init__ will call Base1.__init__(foo='foo', bar='bar'), which
extracts its argument and then calls (surprise!)
Base2.__init__(bar='bar'), which again extracts its argument and then
calls object.__init__(), ending the chain.

Of course if you create an instance of Base1, then the Base1 super
call will next call object.__init__ directly, instead of
Base2.__init__.  This happens because Base2 occurs after Base1 in the
MRO for the class Derived, but Base2 does not appear at all in the MRO
for the class Base1.



More information about the Python-list mailing list