1. 程式人生 > >求助:Python菱形繼承傳參問題,是否應該使用super?每一個父類都有各自引數該如何傳參?以及使用了super之後父類還能否獨自生成物件?

求助:Python菱形繼承傳參問題,是否應該使用super?每一個父類都有各自引數該如何傳參?以及使用了super之後父類還能否獨自生成物件?

Python菱形繼承 傳參問題

類A,
類B,C均繼承於A
類D繼承與(B, C)
程式碼如下:

class A:
    def __init__(self, a):
        print("Enter A")
        self.a = a
        print("Leave A")

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

上面的感覺沒有問題,但是到D的時候:

class D(A, B, C):
        def __init__(self, a, b, c, d):
                print("Enter D")
                super(D, self).__init__(…)  # here!
self.__d = d print("Leave D") def __str__(self): return "Class D: a =" + str(self.a) + " b = " + str(self.b) \ + " c = " + str(self.c) + " d = " + str(self.__d)

在super這裡我剛開始不知道怎麼寫,因為D繼承了B和C,那麼super返回的是B還是C?
查了資料我知道了所謂的MRO,會將D上面的所有類都初始化一遍,於是將類D的super修改如下:
嘗試1


super(D, self).__init__(a, b, c)
對於main:
`
def main():
# aClass = A(2)
# print(aClass)
# bClass = B(3, 4)
# print(bClass)
dClass = D(5, 6, 7, 8)
print(dClass.b)
print(dClass)

main() # Call the main function.

結果執行結果是:

Enter D
Traceback (most recent call last):
File “2.py”, line 50, in
main() # Call the main function.
File “2.py”, line 46, in main
dClass = D(5, 6, 7, 8)
File “2.py”, line 33, in init
super(D, self).init(a, b, c)
TypeError: init() takes 3 positional arguments but 4 were given`
嘗試2:給B類新增一個引數c,(猜測引數c會先傳給D->B->C)將B類修改如下:

class B(A):
    def __init__(self, a, b, c):
        print("Enter B")
        super(B, self).__init__(a, c)
        self.b = b
        print("Leave B")

    def __str__(self):
        return "Class B: a = " + str(self.a) + " b = " + str(self.b)

執行成功,結果是:

Enter D
Enter B
Enter C
Enter A
Leave A
Leave C
Leave B
Leave D
6
Class D: a =5 b = 6 c = 7 d = 8```
至此,D類大概是沒有問題了,但是仍然感覺B類這樣很奇怪,
**問題1**:請問可以這樣用嗎?我是根據報錯資訊一次一次嘗試猜測出這樣一種方法。
**問題2**:感覺上好像B類這樣定義跟B類的初衷不太符合,這樣的B類是否可以單獨拿出來建立自己的物件?
**嘗試3**:單獨建立一個B類的物件bClass:

def main():
# aClass = A(2)
# print(aClass)
bClass = B(3, 4)
“`
報錯如下:
bClass = B(3, 4)
TypeError: init() missing 1 required positional argument: ‘c’
到此為止,我想不出什麼解決的辦法了,
**問題3:如果我前面的步驟是對的,那麼是否可以這樣理解,super使得D, B, C, A按照MRO的順序連結繫結到了一起,這樣最終D的物件可以被成功建立,並且各父類均只初始化一次,但是代價就是,各父類A, B, C不能再單獨建立自己的物件?
問題4:如果這不是正確的方法,請問應該怎麼做**