2

I don't know what does super().__init__(*args, **kwargs) do here.

class B(type):
    def __init__(self, *args, **kwargs):
        self.a = 'a'
        super().__init__(*args, **kwargs)


class A(metaclass=B):
    pass

As i know that super() returns an instance of a super class that tracks the current position in the MRO. When calling a method on a super instance, super looks up the next class in the MRO and calls the method on that class.

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

The super().__init__(*args, **kwargs) call <class 'type'>'s __init__ method,what does it mean?

If i delete it

class B(type):
    def __init__(self, *args, **kwargs):
        self.a = 'a'


class A(metaclass=B):
    pass

Initialize A class

x=A()
x.a
'a'

The instance x belong to A class still own the attribution a, it take same effect .

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
showkey
  • 482
  • 42
  • 140
  • 295
  • It just passes any positional and keyword arguments to the parent's "constructor". – ddejohn Oct 06 '21 at 02:31
  • It take same effect without passing the positional and keyword arguments to the parent's "constructor". – showkey Oct 06 '21 at 02:35
  • it passes those arguments to it parent constructor in order to do anything that need to be done in its construction, for this particular example putting that line or not change nothing, but it might be necessary for a more elaborate inheritance scheme – Copperfield Oct 06 '21 at 02:39
  • Please give a concrete example. – showkey Oct 06 '21 at 02:41

1 Answers1

3

here is a quick sample

>>> class A:
        def __init__(self, a="a",*argv,**karg):
            super().__init__(*argv,**karg)
            self.a=a

    
>>> class B(A):
        def __init__(self, b="b",*argv,**kargv):
            super().__init__(*argv,**kargv)
            self.b=b

        
>>> class Bad(B):
        def __init__(self,b="bad",*arg,**kargv):
            self.b=b

        
>>> b=B()
>>> b.a
'a'
>>> b.b
'b'
>>> bad=Bad()
>>> bad.b
'bad'
>>> bad.a
Traceback (most recent call last):
  File "<pyshell#220>", line 1, in <module>
    bad.a
AttributeError: 'Bad' object has no attribute 'a'
>>> 

Here A is our the base class, and we want that any subclass of it have all the features of A plus any extra the subclass have, then to add new features we just subclass it and use super to delegate to our parent the part that A know how to do so we don't repeat those part, and here B is a subclass that stick to this principle.

Now Bad is a subclass that doesn't stick to this principle and thus would not have any feature that is set in construction in the A parent and thus it would not have its .a attribute set because it refuses to be cooperative by not calling its parent constructor via super.

Some related explaining video: Raymond Hettinger - Super considered super! - PyCon 2015

Copperfield
  • 8,131
  • 3
  • 23
  • 29