Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

demystify super in python?

Tags:

python

super

I was trying to understand how super works in python and tried the following example:

class A(object):
    def __init__(self):
        print "in A's init"

class B(object):
    def __init__(self):
        print "in B's init"

class C(A,B):
    def __init__(self):
        super(C,self).__init__()
        print "In C"

if __name__=="__main__":
    c=C()

fairly simple.. And I tried the following super calls(displayed with the results here):

>>> super(B,c).__init__()
>>> super(B,c).__init__()
>>> super(A,c).__init__()
    in B's init
>>> super(A,c).__init__()
    in B's init
>>> super(A,c).__init__()
    in B's init
>>> super(B,c).__init__()
>>> super(C,c).__init__()
    in A's init

I do not understand why does super(A,c).__init__() print out that its in B's init??

like image 315
py_newbie Avatar asked Jan 11 '23 06:01

py_newbie


1 Answers

Python's super() should have been been called "next-in-mro" because it doesn't necessarily call upwards to a parent; rather, it can call a sibling instead.

It is easy to inspect the method resolution order of your class structure:

 >>> C.__mro__
 (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

You can see that B is the next class after A.

The reason for this design is that it lets the chain of super calls visit every class in the chain no more than once. That supports a style of programming called "cooperative multiple inheritance" which is sometimes very useful.

Here are some references including links to Dylan's next-method that served as a model for Python's super():

  • http://opendylan.org/books/drm/Method_Dispatch#HEADING-50-32
  • http://rhettinger.wordpress.com/2011/05/26/super-considered-super/
  • http://opendylan.org/proposals/dep-0003.html
  • http://www.artima.com/weblogs/viewpost.jsp?thread=281127
like image 168
Raymond Hettinger Avatar answered Jan 23 '23 21:01

Raymond Hettinger