web-dev-qa-db-ja.com

TypeError:python異なる引数による多重継承

複数の継承を使用して、既存のクラスの1つにいくつかの機能を追加しようとしています。問題は、この新しいクラスと現在の基本クラスのコンストラクターで引数が異なることです。つまり、新しいクラスには1つの追加の引数があります。グーグルで調べたところ、現在の基本クラス(引数が1つ少ないクラス)に** kwargsを追加できることがわかりました。例:

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)

しかし、私はこのエラーを受け取ります:

<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

対処しようとしているビジネスケースが何であり、この特定の形式の継承を推進しているものを知るのは困難です。そうは言っても、クラス 'I'は最初に 'E'のinitを呼び出し、次に 'H'の呼び出しを行うため、例外が発生します。

この問題を解決する最も簡単な方法は、私がベースクラスの順序をあなたのケースでより自然に見えるものに切り替えることです:

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())

これは問題を解決します。

0
Roy2012