TypeError:具有不同参数的python多重继承

我正在尝试使用多重继承向我拥有的现有类之一添加一些功能。问题是这个新类和我当前的基类在它们的构造函数中有不同的参数。即新类有 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'


Cats萌萌
浏览 158回答 3
3回答

波斯汪

这段代码对我有用!!!class A(object):&nbsp; &nbsp; def __init__(self, a):&nbsp; &nbsp; &nbsp; &nbsp; print("A class")class B(A):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; A.__init__(self,a)&nbsp; &nbsp; &nbsp; &nbsp; print("B class")class C(B):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; B.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; print("C class")class D(C):&nbsp; &nbsp; def __init__(self, a,b):&nbsp; &nbsp; &nbsp; &nbsp; C.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; print("D class")class F(C):&nbsp; &nbsp; def __init__(self, a,b):&nbsp; &nbsp; &nbsp; &nbsp; #C.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; print("F class")class G(F):&nbsp; &nbsp; def __init__(self, a, b, c):&nbsp; &nbsp; &nbsp; &nbsp; F.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; print("G class")class E(D):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; D.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; print("E class")class H(G):&nbsp; &nbsp; def __init__(self, a,b,c):&nbsp; &nbsp; &nbsp; &nbsp; G.__init__(self,a, b, c)&nbsp; &nbsp; &nbsp; &nbsp; print("H class")class I(E,H):&nbsp; &nbsp; def __init__(self, a, b, c):&nbsp; &nbsp; &nbsp; &nbsp; args=(a,b,c)&nbsp; &nbsp; &nbsp; &nbsp; E.__init__(self,a,b)&nbsp; &nbsp; &nbsp; &nbsp; H.__init__(self,a,b,c)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())print(I.__mro__)I(1,2,3)

RISEBY

根据 MRO,调用转到Hafter D,因此,如果您需要 send c,类D将需要接受它并发送 3 个参数,即。H将被调用D。例如:class A(object):&nbsp; &nbsp; def __init__(self, a):&nbsp; &nbsp; &nbsp; &nbsp; print('a')&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class B(A):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; print('b')&nbsp; &nbsp; &nbsp; &nbsp; super(B, self).__init__(a)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class C(B):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; print('c')&nbsp; &nbsp; &nbsp; &nbsp; super(C, self).__init__(a, b)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class D(C):&nbsp; &nbsp; def __init__(self, a, b, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; print('d', args, kwargs)&nbsp; &nbsp; &nbsp; &nbsp; super(D, self).__init__(a, b, args, kwargs)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class E(D):&nbsp; &nbsp; def __init__(self, a, b, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; print('e', args, kwargs)&nbsp; &nbsp; &nbsp; &nbsp; super(E, self).__init__(a, b)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class F(C):&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; print('f')&nbsp; &nbsp; &nbsp; &nbsp; super(F, self).__init__(a, b)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class G(F):&nbsp; &nbsp; def __init__(self, a, b, c):&nbsp; &nbsp; &nbsp; &nbsp; print('g')&nbsp; &nbsp; &nbsp; &nbsp; super(G, self).__init__(a, b)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class H(G):&nbsp; &nbsp; def __init__(self, a, b, c, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; print('h')&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; super(H, self).__init__(a, b, c)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())class I(E,H):&nbsp; &nbsp; def __init__(self, a, b, c):&nbsp; &nbsp; &nbsp; &nbsp; print('i')&nbsp; &nbsp; &nbsp; &nbsp; super(I,self).__init__(a, b, c)&nbsp; &nbsp; &nbsp; &nbsp; #E.__init__(self,a, b)&nbsp; &nbsp; &nbsp; &nbsp; #H.__init__(self,a, b, c)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())for c in I.__mro__:&nbsp; &nbsp; &nbsp; &nbsp; print(c)I(0, 1, 2)此代码有效,(我已更改c为 arg 而不是**kwarg)。另一种方法是,如果您交换E,H继承顺序,MRO 就可以解决,您就不需要这样做,或者单独使用E.__init__()and H.__init__()。在这种情况下,MRO 会再次发生变化,如果需要,公共类将被调用两次。对于 MRO,我找到了这个答案和Guido Van Rossum 的这篇博客文章(也链接在另一个答案中),这可能有助于您深入了解 Python 中的 MRO 算法。

达令说

很难知道您要处理的业务案例是什么,以及是什么驱动了这种特定的继承形式。话虽这么说,你得到了例外,因为类'I'首先调用'E'的init,然后才调用'H'。解决该问题的最简单方法是将 I 的基类的顺序切换为在您的情况下看起来更自然的顺序:class I(H, E):&nbsp; # original code was I(E, H)&nbsp;&nbsp; &nbsp; def __init__(self, a, b, c):&nbsp; &nbsp; &nbsp; &nbsp; super(I, self).__init__(a, b, c=c)&nbsp; &nbsp; &nbsp; &nbsp; print('__init__', locals())这解决了这个问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python