Множественное наследование, TypeError: __init__() принимает 2 позиционных аргумента, но дано 3

Я изучаю множественное наследование класса

class A(): 
    def __init__(self, a): 
        super().__init__() 
        self.a = a                                                                                                                                             

class B(): 
    def __init__(self, b): 
        super().__init__() 
        self.b = b 
         
class C(A, B): 
    def __init__(self, a, b, c): 
        super().__init__(a, b) 
        self.c = c 

C(1, 2, 3) приводит к ошибке TypeError: __init__() takes 2 positional arguments but 3 were given

Я хочу, чтобы он мог инициализироваться в порядке A-> B-> C, я все еще застреваю после поиска существующих связанных вопросов

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
1 977
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вам нужно указать определенные аргументы для определенных суперклассов, вам нужно будет сделать это явно:

class A(): 
    def __init__(self, a): 
        self.a = a                                                                                                                                             

class B(): 
    def __init__(self, b): 
        self.b = b 
         
class C(A, B): 
    def __init__(self, a, b, c): 
        A.__init__(self, a) 
        B.__init__(self, b)
        self.c = c

Обратите внимание, что вы также не можете больше выполнять super().__init__() в классах A и B, потому что super на самом деле вызывает не суперкласс класса, в котором он «записан», а следующий класс в порядке разрешения методов.

Обычно такой код указывает на плохой дизайн/неправильное использование подклассов.


Кроме того, вы можете обойти это, используя аргументы ключевого слова:

class A(): 
    def __init__(self, *, a, **kwargs):
        super().__init__(**kwargs)
        self.a = a

class B(): 
    def __init__(self, *, b, **kwargs): 
        super().__init__(**kwargs)
        self.b = b 

class C(A, B): 
    def __init__(self, a, b, c): 
        super().__init__(a=a, b=b)
        self.c = c
Ответ принят как подходящий

Сделайте базовые классы более гибкими, заставив их передавать дополнительные *args супервызову:

class A(): 
    def __init__(self, a, *args): 
        super().__init__(*args) 
        self.a = a
        

class B(): 
    def __init__(self, b, *args): 
        super().__init__(*args) 
        self.b = b 
      

class C(A, B): 
    def __init__(self, a, b, c): 
        super().__init__(a, b) 
        self.c = c 

>>> c = C(1,2,3)
>>> c.a
1
>>> c.b
2
>>> c.c
3

Было бы еще лучше использовать аргументы ключевого слова, чтобы не полагаться на mro:

class A(): 
    def __init__(self, a=None, **kwargs): 
        super().__init__(**kwargs) 
        self.a = a
        

class B(): 
    def __init__(self, b=None, **kwargs): 
        super().__init__(**kwargs) 
        self.b = b
      

class C(A, B): 
    def __init__(self, a, b, c): 
        super().__init__(a=a, b=b) 
        self.c = c 

Теперь class C(B, A) будет работать так, как ожидалось.

Другие вопросы по теме