Что делает super().__init__(*args, **кварги)?

#python #python-3.x #metaclass

Вопрос:

Я не знаю, что super().__init__(*args, **kwargs) здесь происходит.

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


class A(metaclass=B):
    pass
 

Насколько я знаю, super() возвращает экземпляр суперкласса, который отслеживает текущее положение в MRO. При вызове метода в экземпляре super super ищет следующий класс в MRO и вызывает метод в этом классе.

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

super().__init__(*args, **kwargs) Вызов метода <class ‘type’>’s <class ‘type’> __init__ , что это значит?

Если я удалю его

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


class A(metaclass=B):
    pass
 

Инициализировать A класс

 x=A()
x.a
'a'
 

Экземпляр x принадлежит A классу , все еще владеющему атрибуцией a , она действует так же .

Комментарии:

1. Он просто передает любые позиционные и ключевые аргументы в родительский «конструктор».

2. Это будет иметь тот же эффект без передачи позиционных и ключевых аргументов в «конструктор»родителя.

3. он передает эти аргументы своему родительскому конструктору, чтобы сделать все, что нужно сделать при его построении, для данного конкретного примера, помещая эту строку или ничего не меняя, но это может потребоваться для более сложной схемы наследования

4. Пожалуйста, приведите конкретный пример.

Ответ №1:

вот краткий пример

 >>> 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'
>>> 
 

Здесь A будет наш базовый класс, и мы хотим, чтобы любой подкласс этого есть все возможности, плюс любые дополнительные подкласс, то для добавления новых функций мы просто создать его подкласс и использовать супер делегировать наша материнская часть, которая A знает, как сделать это нам не повторить те части, а тут B является подклассом, что придерживаться этого принципа.

Теперь Bad это подкласс, который не придерживается этого принципа и, следовательно, не будет иметь какой-либо функции, заданной при построении в A родительском, и, следовательно, у него не будет .a набора атрибутов, потому что он отказывается сотрудничать, не вызывая родительский конструктор через super.

Некоторые связанные объяснительные видео: Раймонд Хеттингер — Супер, супер! — PyCon 2015