Python - which is the better way of calling superclass' method?

后端 未结 3 1275
有刺的猬
有刺的猬 2021-01-04 02:29

All the while I have been using:

SuperClass.__init__(self, *args, **kwargs)

My reason is that this shows explicitly which superclass is use

相关标签:
3条回答
  • 2021-01-04 02:53

    For new style classes which inherit from object, super is used.

    The __mro__ (method resolution order) attribute of the type lists the method resolution search order used by super.

    >>> class X(object):
        pass
    
    >>> class Y(object):
        pass
    
    >>> class Z(X, Y):
        pass
    
    >>> Z.__mro__
    (<class '__main__.Z'>, <class '__main__.X'>, <class '__main__.Y'>, <type 'object'>)
    

    This specifies the ordering for Z. Since it is Z(X, Y), X is first in the hierarchy. Had it been Z(Y, X), Y would have preceded over X.

    For old style classes, SuperClass.__init__(self, *args, **kwargs) is used.

    UPDATE:

    For your question as to which SuperClass is being used.

    >>> class First(object):
        pass
    
    >>> class Second(object):
        def __init__(self, *args, **kwargs):
            print 'Second __init__ called'
    
    >>> class MInherit(First, Second):
        def __init__(self):
            super(MInherit, self).__init__()
    
    >>> i = MInherit()
    Second __init__ called
    

    First, First will be checked to see if it has an __init__, since First comes first in the MRO. Since in this case 'First' doesn't have an __init__, so Second is called. Had there been an __init__ in First, only that would have been called.

    0 讨论(0)
  • 2021-01-04 02:55

    In addition to the good answers already posted, here is some additional info:

    • Old-style classes (those that don't derive from object) have a depth-first method resolution order. Old-style classes call their super classes in the way that you are used to.

    • New-style classes (those that do derive from object) have a more complicated method resolution order. At the highest level it is akin to breadth first, but is more complex than that. See this page for an excellent explanation. Using "super()" allows new style classes to follow this method resolution order.

    • If you are using new-style classes, you can still use the old-style of calling super classes and your code will still work. The differences only become apparent for more complicated multiple-inheritance patterns.

    0 讨论(0)
  • 2021-01-04 03:01

    The reason that super is prefereable for modern (new style) classes is that it allows cooperative multiple inheritance. Here's an example.

    >>> class Foo(object):
    ...     def display(self):
    ...         print "In Foo"
    ... 
    >>> class Foo2(Foo):
    ...     def display(self):
    ...         print "In Foo2"
    ...         super(Foo2, self).display()
    ...         print "Back in Foo2"
    ... 
    >>> class Bar(Foo):
    ...     def display(self):
    ...         print "In Bar"
    ...         super(Bar, self).display()
    ...         print "Back in Bar"
    ... 
    >>> class FooBar(Foo2, Bar):
    ...     pass
    ... 
    >>> FooBar().display()
    In Foo2
    In Bar
    In Foo
    Back in Bar
    Back in Foo2
    >>> class BarFoo(Bar, Foo2):
    ...     pass
    ... 
    >>> BarFoo().display()
    In Bar
    In Foo2
    In Foo
    Back in Foo2
    Back in Bar
    

    Note that I didn't do anything to change the display method on the superclasses but I got different display methods on the subclasses by changing the order in which I arranged the superclasses. BarFoo and FooBar have different methods. This is because they have different Method Resolution Orders

    >>> BarFoo.__mro__
    (<class '__main__.BarFoo'>, <class '__main__.Bar'>, <class '__main__.Foo2'>, <class '__main__.Foo'>, <type 'object'>)
    >>> FooBar.__mro__
    (<class '__main__.FooBar'>, <class '__main__.Foo2'>, <class '__main__.Bar'>, <class '__main__.Foo'>, <type 'object'>)
    

    This means that super resolves to a different class for each subclass that it's called in. This allows for each overriding method to change a small part of what's going on and still let every other superclass contribute to the method call as long as they're willing to play nicely.

    0 讨论(0)
提交回复
热议问题