【Python求助】关于带参数的钻石继承问题
本帖最后由 Paranoid丶 于 2021-1-29 13:47 编辑这几天在自学Python,但学到类的继承的时候自己尝试出现了问题,使用的python版本为3.6.6
自己在百度上找了很久,没找到可以参照的例子,满屏的CSDN基本都是同一篇文章。。、
### 问题描述
钻石继承带参数的时候,运行到最后一个类出现错误:`__init__() missing 1 required positional argument: 'c'`
### 程序代码
```python
class A:
def __init__(self,a):
self.a=a
print(self.a)
class B(A):
def __init__(self,a,b):
super().__init__(a)
self.b=b
print(self.b)
class C(A):
def __init__(self,a,c):
super().__init__(a)
self.c=c
print(self.c)
class D(B,C):
def __init__(self,a,b,c,d):
B.__init__(self,a,b)
C.__init__(self,a,c)
self.d=d
print(self.d)
def main():
A(1)
B(2,3)
C(4,5)
D(6,7,8,9)
if __name__=='__main__':
main()
``` 本帖最后由 ufo0033 于 2021-1-29 13:41 编辑
python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么b的super().__init__(a)实际上是在给c 初始化。这里开始参数不对了,
class A:
def __init__(self, a, *args, **kwargs):
print('进入A')
self.a = a
print("A message:", self.a)
print('离开A')
class B(A):
def __init__(self, b, *args, **kwargs):
print('进入B')
super(B, self).__init__(*args, **kwargs)
self.b = b
print("B message:", self.b)
print('离开B')
class C(A):
def __init__(self, c, *args, **kwargs):
print('进入C')
super(C, self).__init__(*args, **kwargs)
self.c = c
print("C message:",self.c)
print('离开C')
class D(B, C):
def __init__(self, d, *args, **kwargs):
print('进入D')
super(D, self).__init__(*args, **kwargs)
self.d = d
print("D message:",self.d)
print('离开D')
def main():
# A(1)
# B(2, 3)
# C(4, 5)
D(6, 7, 8, 9)
if __name__ == '__main__':
main()
这样设计的目的是为了防止 A被多次初始化 看描述应该是说参数3个但是你给了4个 D的父类都没有接受3个参数的 __init__方法,肯定会报错啊 gongsui 发表于 2021-1-29 11:07
看描述应该是说参数3个但是你给了4个
但是我在super给的参数是三个:a,b,c jiangpeng59 发表于 2021-1-29 11:09
D的父类都没有接受3个参数的 __init__方法,肯定会报错啊
{:301_1009:}所以没有办法接受多个父类的参数吗 试了下好像class B 里的那个super会调用A的__init__然后还会调用C的__init__,所以报错,原理不知道
另外,为啥用B.__init__(self) 这种方式啊 class A:
def __init__(self,a):
self.a=a
print(self.a)
class B(A):
def __init__(self,a,b):
A.__init__(self, a)
self.b=b
print(self.b)
class C(A):
def __init__(self,a,c):
A.__init__(self, a)
self.c=c
print(self.c)
class D(B,C):
def __init__(self,a,b,c,d):
B.__init__(self, a,b)
C.__init__(self, a,c)
self.d=d
print(self.d)
def main():
A(6)
B(6,7)
C(6,7)
D(6,7,8,9)
if __name__=='__main__':
main()
这样没问题,至于为什么我也不知道,python我不熟悉,不过构造顺序到是和c++的规则一样 ufo0033 发表于 2021-1-29 13:20
python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么b的super().__init__(a)实际上 ...
学到了,感谢 ufo0033 发表于 2021-1-29 13:20
python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么b的super().__init__(a)实际上 ...
这种设计牛逼阿,免去了一次构造和析构,不知道C++种有没有这种解决方案
页:
[1]
2