求助: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:如果這不是正確的方法,請問應該怎麼做**