Skip to content Skip to sidebar Skip to footer

Using Super Without Inheritance Class In Python3

anyone know what it means for following code on super(xxx, self).__init__()? what does it do? I though it should be class ABC inherits from other class but I do not see which class

Solution 1:

super works with the method resolution order (MRO) of the class. The MRO always contains at least two classes: the class itself, and object (because all classes implicitly inherit from object)

>>> classABC: pass
...
>>> ABC.__mro__
(<class'__main__.ABC'>, <class'object'>)

If there are any explicitly named base classes in the class statement, those and their base classes will appear in the MRO somewhere between the new class and object.

>>> classABC(str): pass
...
>>> ABC.__mro__
(<class'__main__.ABC'>, <class'str'>, <class'object'>)

Regarding your question "why super?", consider this standard example:

classA:
    deffoo(self):
        print("A")


classB(A):
    deffoo(self):
        super().foo()
        print("B")


classC(A):
    deffoo(self):
        super().foo()
        print("C")


classD(B, C):
    deffoo(self):
        super().foo()
        print("D")

The MRO for D is (D, B, C, A). Notice the call super().foo in B.foo. Looking only at the class B, you might assume that super().foo() is a call to A.foo. But when self is an instance of D (as is the case with D().foo(), for example), then super refers to C, not A, because C comes immediately after B in the MRO.

>>> D().foo()
A
C
B
D

foo outputs the classes in the MRO (sansobject; A doesn't use super because A "introduced" foo into the hierarchy) in reverse order, from least to most specific.

Solution 2:

Classes without explicit bases automatically inherit from object. When called via ABC(), the super(ABC, self).__init__() inside ABC.__init__ executes object.__init__. This can be seen by checking the method resolution order.

>>> ABC.__mro__
(__main__.ABC, object)

Methods that do nothing but invoke the super method are generally not needed. However, when adding functionality it is common to invoke super even to refer to object.


Notably, super dispatch is not static, but can change via inheritance. Multiple inheritance can be used to inject another class between ABC and object in the method resolution order.

>>>classIntermediate:...def__init__(self):...print(f'Intermediate init of {self.__class__.__name__}')...super().__init__()...>>>classAlphabet(ABC, Intermediate):..."""Compound of ABC and Intermediate"""...>>>Alphabet.__mro__                   # Intermediate is between ABC and object...
(__main__.Alphabet, __main__.ABC, __main__.Intermediate, object)
>>>Alphabet.__init__ is ABC.__init__  # ... but __init__ is still identical!
True
>>>Alphabet()  # Alphabet's ABC.__init__ delegates to Intermediate.__init__ ...
Intermediate init of Alphabet
>>>ABC()       # ... but ABC's ABC.__init__ still does not.

A class such as Intermediate is generally known as a mixin. In Python, classes intended to be used with mixins must use super instead of directly referring to superclass methods.

Solution 3:

All classes implicitly inherit from object, just like in Java, unless they explicitly inherit from something else (which itself has to either implicitly inherit from object or from something else, and so on...).

A byproduct of this is that you can invoke any of object's methods on your object, ignoring your object's implementation of those methods, by doing what you've done:

>>> dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
 '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
 '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
 '__sizeof__', '__str__', '__subclasshook__']

Post a Comment for "Using Super Without Inheritance Class In Python3"