亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

TypeError:具有不同參數的python多重繼承

TypeError:具有不同參數的python多重繼承

Cats萌萌 2022-11-01 17:16:28
我正在嘗試使用多重繼承向我擁有的現有類之一添加一些功能。問題是這個新類和我當前的基類在它們的構造函數中有不同的參數。即新類有 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'
查看完整描述

3 回答

?
波斯汪

TA貢獻1811條經驗 獲得超4個贊

這段代碼對我有用?。。?/p>


class A(object):

    def __init__(self, a):

        print("A class")



class B(A):

    def __init__(self, a, b):

        A.__init__(self,a)

        print("B class")




class C(B):

    def __init__(self, a, b):

        B.__init__(self,a, b)

        print("C class")




class D(C):

    def __init__(self, a,b):

        C.__init__(self,a, b)

        print("D class")



class F(C):

    def __init__(self, a,b):

        #C.__init__(self,a, b)

        print("F class")



class G(F):

    def __init__(self, a, b, c):

        F.__init__(self,a, b)

        print("G class")


class E(D):

    def __init__(self, a, b):

        D.__init__(self,a, b)

        print("E class")



class H(G):

    def __init__(self, a,b,c):

        G.__init__(self,a, b, c)

        print("H class")



class I(E,H):

    def __init__(self, a, b, c):

        args=(a,b,c)

        E.__init__(self,a,b)

        H.__init__(self,a,b,c)

        print('__init__', locals())



print(I.__mro__)

I(1,2,3)


查看完整回答
反對 回復 2022-11-01
?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

根據 MRO,調用轉到Hafter D,因此,如果您需要 send c,類D將需要接受它并發送 3 個參數,即。H將被調用D。例如:


class A(object):

    def __init__(self, a):

        print('a')

        print('__init__', locals())


class B(A):

    def __init__(self, a, b):

        print('b')

        super(B, self).__init__(a)


        print('__init__', locals())


class C(B):

    def __init__(self, a, b):

        print('c')

        super(C, self).__init__(a, b)


        print('__init__', locals())


class D(C):

    def __init__(self, a, b, *args, **kwargs):

        print('d', args, kwargs)

        super(D, self).__init__(a, b, args, kwargs)


        print('__init__', locals())


class E(D):

    def __init__(self, a, b, *args, **kwargs):

        print('e', args, kwargs)

        super(E, self).__init__(a, b)


        print('__init__', locals())


class F(C):

    def __init__(self, a, b):

        print('f')

        super(F, self).__init__(a, b)


        print('__init__', locals())


class G(F):

    def __init__(self, a, b, c):

        print('g')

        super(G, self).__init__(a, b)


        print('__init__', locals())


class H(G):

    def __init__(self, a, b, c, *args, **kwargs):

        print('h')        

        super(H, self).__init__(a, b, c)


        print('__init__', locals())


class I(E,H):

    def __init__(self, a, b, c):

        print('i')

        super(I,self).__init__(a, b, c)

        #E.__init__(self,a, b)

        #H.__init__(self,a, b, c)


        print('__init__', locals())


for c in I.__mro__:

        print(c)


I(0, 1, 2)

此代碼有效,(我已更改c為 arg 而不是**kwarg)。另一種方法是,如果您交換E,H繼承順序,MRO 就可以解決,您就不需要這樣做,或者單獨使用E.__init__()and H.__init__()。在這種情況下,MRO 會再次發生變化,如果需要,公共類將被調用兩次。

對于 MRO,我找到了這個答案和Guido Van Rossum 的這篇博客文章(也鏈接在另一個答案中),這可能有助于您深入了解 Python 中的 MRO 算法。



查看完整回答
反對 回復 2022-11-01
?
達令說

TA貢獻1821條經驗 獲得超6個贊

很難知道您要處理的業務案例是什么,以及是什么驅動了這種特定的繼承形式。話雖這么說,你得到了例外,因為類'I'首先調用'E'的init,然后才調用'H'。


解決該問題的最簡單方法是將 I 的基類的順序切換為在您的情況下看起來更自然的順序:


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

這解決了這個問題。


查看完整回答
反對 回復 2022-11-01
  • 3 回答
  • 0 關注
  • 181 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號