web-dev-qa-db-fra.com

TypeError: python héritage multiple avec différents arguments

J'essaie d'utiliser l'héritage multiple pour ajouter des fonctionnalités à l'une des classes existantes que j'ai. Le problème est que cette nouvelle classe et ma classe de base actuelle ont des arguments différents dans leurs constructeurs. A savoir, la nouvelle classe a 1 argument supplémentaire. Après quelques recherches sur Google, j'ai compris que je pouvais ajouter ** kwargs à la classe de base actuelle (celle avec un argument en moins). Exemple:

class A(object):
    def __init__(self, a):
        print('__init__', locals())


class B(A):
    def __init__(self, a, b):
        super(B, self).__init__(a)
        print('__init__', locals())


class C(B):
    def __init__(self, a, b):
        super(C, self).__init__(a, b)
        print('__init__', locals())


class D(C):
    def __init__(self, a, b):
        super(D, self).__init__(a, b)
        print('__init__', locals())


class E(D):
    def __init__(self, a, b, *args, **kwargs):
        super(E, self).__init__(a, b)
        print('__init__', locals())


class F(C):
    def __init__(self, a, b):
        super(F, self).__init__(a, b)
        print('__init__', locals())


class G(F):
    def __init__(self, a, b, c):
        super(G, self).__init__(a, b)
        print('__init__', locals())


class H(G):
    def __init__(self, a, b, c):
        super(H, self).__init__(a, b, c)
        print('__init__', locals())


class I(E, H):
    def __init__(self, a, b, c):
        super(I, self).__init__(a, b, c=c)
        print('__init__', locals())


for c in I.__mro__:
        print(c)


I(0, 1, 2)

Mais j'obtiens cette erreur:

<class '__main__.I'>
<class '__main__.E'>
<class '__main__.D'>
<class '__main__.H'>
<class '__main__.G'>
<class '__main__.F'>
<class '__main__.C'>
<class '__main__.B'>
<class '__main__.A'>
<class 'object'>
Traceback (most recent call last):
  File "/tmp/c.py", line 58, in <module>
    I(0,1,2)
  File "/tmp/c.py", line 50, in __init__
    super(I, self).__init__(a, b, c=c)
  File "/tmp/c.py", line 26, in __init__
    super(E, self).__init__(a, b)
  File "/tmp/c.py", line 20, in __init__
    super(D, self).__init__(a, b)
TypeError: __init__() missing 1 required positional argument: 'c'
8
Bob Sacamano

Il est difficile de savoir quelle est l'analyse de rentabilisation que vous essayez de traiter et ce qui motive cette forme spécifique d'héritage. Cela étant dit, vous obtenez l'exception parce que la classe "I" appelle d'abord init de "E", et seulement ensuite de "H".

Le moyen le plus simple de résoudre le problème serait de changer l'ordre des classes de base de I sur ce qui semble plus naturel dans votre cas:

class I(H, E):  # original code was I(E, H) 
    def __init__(self, a, b, c):
        super(I, self).__init__(a, b, c=c)
        print('__init__', locals())

Cela résout le problème.

0
Roy2012