I have a Python ABC (let's call it A
) with a concrete __init__()
method, as well as a class that implements this ABC (let's call it B
). As far as I understand, I should not be able to instantiate the ABC.
Question: Why and how is the call super().__init__()
inside the __init__
function of class B
working? I assume that super()
creates an instance of the parent class - which in this case is the ABC.
Class A
from abc import ABC, abstractmethod
from util.fileManager import FileManager
class A(ABC):
def __init__(self):
self.file_manager = FileManager() # Composition object
...
Class B, implementing class A
from interfaces.A import A
class B(A):
def __init__(self):
super().__init__()
...
CodePudding user response:
super()
does not create an instance of the parent.
An instance of super
(it's a type, not a function) provides a proxy for for some set of classes so that an attribute lookup resolves to the correct class's value. Calling super().__init__
simply starts looking in the MRO of type(self)
, starting at A
, for an attribute named __init__
.
When arguments are explicitly provided to super
, the second argument determines whose MRO you will search, and the first argument determines where in the MRO you start search (namely, the next class after the argument in the MRO).
An example with an extremely unorthodox use of super
:
>>> class A:
... def foo(self):
... print("A")
...
>>> class B(A):
... def foo(self):
... print("B")
...
>>> b = B()
>>> x = super(B, b)
>>> type(x)
<class 'super'>
>>> x.__thisclass__
<class '__main__.B'>
>>> x.__self__ is b
True
>>> x.foo()
A
super
itself doesn't really have optional arguments, but the context in which you almost always use it strongly imply which arguments should be passed, so Python 3 was engineered to supply them for you.