trouble understanding super()

Discussion in 'Python' started by John Salerno, Jul 31, 2006.

  1. John Salerno

    John Salerno Guest

    Here's some code from Python in a Nutshell. The comments are lines from
    a previous example that the calls to super replace in the new example:

    class A(object):
    def met(self):
    print 'A.met'

    class B(A):
    def met(self):
    print 'B.met'
    # A.met(self)
    super(B, self).met()

    class C(A):
    def met(self):
    print 'C.met'
    # A.met(self)
    super(C, self).met()

    class D(B, C):
    def met(self):
    print 'D.met'
    # B.met()
    # C.met()
    super(D, self).met()

    Then you call D().met()

    Now, I understand that the commented code would cause A.met to be called
    twice. But why does the second version (with super) not also do this? I
    guess my problem lies in not understanding exactly what the super
    function returns.

    super(D, self).met() seems like it would return something that has to do
    with both B and C, which each in turn return a superobject having to do
    with A, so why isn't A.met called twice still?

    Thanks!
    John Salerno, Jul 31, 2006
    #1
    1. Advertising

  2. John Salerno

    Simon Forman Guest

    John Salerno wrote:
    > Here's some code from Python in a Nutshell. The comments are lines from
    > a previous example that the calls to super replace in the new example:
    >
    > class A(object):
    > def met(self):
    > print 'A.met'
    >
    > class B(A):
    > def met(self):
    > print 'B.met'
    > # A.met(self)
    > super(B, self).met()
    >
    > class C(A):
    > def met(self):
    > print 'C.met'
    > # A.met(self)
    > super(C, self).met()
    >
    > class D(B, C):
    > def met(self):
    > print 'D.met'
    > # B.met()
    > # C.met()
    > super(D, self).met()
    >
    > Then you call D().met()
    >
    > Now, I understand that the commented code would cause A.met to be called
    > twice. But why does the second version (with super) not also do this? I
    > guess my problem lies in not understanding exactly what the super
    > function returns.
    >
    > super(D, self).met() seems like it would return something that has to do
    > with both B and C, which each in turn return a superobject having to do
    > with A, so why isn't A.met called twice still?
    >
    > Thanks!



    Basically super(class_, self).method looks in self's mro (it's list of
    base classes) for class class_, and then starts searching *after* class
    class_ for the next class that implements the method.

    In this case the object's (instance of D) mro will be (D, B, C, A,
    object), so as super gets called in each class, it looks in that list
    (tuple, whatever) for the class following it (actually the next class
    following it that implements the method).

    Since no class appears in that list more than once, each class's
    implementation of the method will only be called once.


    HTH,
    ~Simon


    Also, if you haven't already, read:
    http://www.python.org/download/releases/2.2.3/descrintro/#cooperation
    Simon Forman, Jul 31, 2006
    #2
    1. Advertising

  3. John Salerno

    John Salerno Guest

    Simon Forman wrote:

    > In this case the object's (instance of D) mro will be (D, B, C, A,
    > object), so as super gets called in each class, it looks in that list
    > (tuple, whatever) for the class following it (actually the next class
    > following it that implements the method).
    >
    > Since no class appears in that list more than once, each class's
    > implementation of the method will only be called once.


    But after super(D, self).met() is called, doesn't that then call both
    super(B, self).met() and super(C, self).met()? If so, how does that
    avoid calling A.met twice? Or is that not what's happening?

    Here's what I think gets called, in order, after running D().met():

    print 'D.met'
    super(D, self).met()
    print 'B.met'
    super(B, self).met()
    print 'A.met'
    print 'C.met'
    super(C, self).met()
    print 'A.met'
    John Salerno, Jul 31, 2006
    #3
  4. John Salerno

    Duncan Booth Guest

    John Salerno wrote:

    > But after super(D, self).met() is called, doesn't that then call both
    > super(B, self).met() and super(C, self).met()? If so, how does that
    > avoid calling A.met twice? Or is that not what's happening?


    If you have an instance of a B then super(B,self).met() will call A.met(),
    but if self is actually an instance of a D, then super(B,self).met()
    actually calls C.met().

    That is why super needs both the class and the instance: so it can jump
    sideways across the inheritance diamond instead of always passing calls to
    the base of the current class.
    Duncan Booth, Jul 31, 2006
    #4
  5. John Salerno

    John Salerno Guest

    Duncan Booth wrote:
    > John Salerno wrote:
    >
    >> But after super(D, self).met() is called, doesn't that then call both
    >> super(B, self).met() and super(C, self).met()? If so, how does that
    >> avoid calling A.met twice? Or is that not what's happening?

    >
    > If you have an instance of a B then super(B,self).met() will call A.met(),
    > but if self is actually an instance of a D, then super(B,self).met()
    > actually calls C.met().
    >
    > That is why super needs both the class and the instance: so it can jump
    > sideways across the inheritance diamond instead of always passing calls to
    > the base of the current class.


    Oh, I think I get it! So what's happening is this:

    1. the MRO in this case is always (D, B, C, A, object)
    2. super(D, self).met() looks in B
    3. super(B, self).met() looks in C
    4. super(C, self).met() looks in A

    Right? So it's like making a ladder? I guess my confusion came when I
    thought that a call to super(B, self).met() also called A.met, but I
    guess it stops at C and lets C call it.
    John Salerno, Jul 31, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest

    super.super.super how?

    Guest, Feb 19, 2005, in forum: Java
    Replies:
    24
    Views:
    10,759
    Darryl Pierce
    Feb 24, 2005
  2. Fernando Rodriguez

    Getting the super class via the super() function

    Fernando Rodriguez, Nov 21, 2003, in forum: Python
    Replies:
    2
    Views:
    720
    Bob Willan
    Nov 22, 2003
  3. Kerim Borchaev

    super. could there be a simpler super?

    Kerim Borchaev, Jan 15, 2004, in forum: Python
    Replies:
    4
    Views:
    476
    Michele Simionato
    Jan 15, 2004
  4. Replies:
    7
    Views:
    450
    Patricia Shanahan
    Apr 6, 2008
  5. GOOD LUCK GROUP
    Replies:
    0
    Views:
    394
    GOOD LUCK GROUP
    Apr 28, 2008
Loading...

Share This Page