吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1133|回复: 11
收起左侧

[已解决] 【Python求助】关于带参数的钻石继承问题

[复制链接]
Paranoid丶 发表于 2021-1-29 10:51
本帖最后由 Paranoid丶 于 2021-1-29 13:47 编辑

这几天在自学Python,但学到类的继承的时候自己尝试出现了问题,使用的python版本为3.6.6

自己在百度上找了很久,没找到可以参照的例子,满屏的CSDN基本都是同一篇文章。。、

问题描述

钻石继承带参数的时候,运行到最后一个类出现错误:__init__() missing 1 required positional argument: 'c'

程序代码

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:20
本帖最后由 ufo0033 于 2021-1-29 13:41 编辑

python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么  b的  super().__init__(a)  实际上是在给c 初始化。  这里开始参数不对了,
[Python] 纯文本查看 复制代码
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被多次初始化

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Paranoid丶 + 1 + 1 谢谢@Thanks!

查看全部评分

gongsui 发表于 2021-1-29 11:07
jiangpeng59 发表于 2021-1-29 11:09
D的父类都没有接受3个参数的 __init__方法,肯定会报错啊
 楼主| Paranoid丶 发表于 2021-1-29 11:09
gongsui 发表于 2021-1-29 11:07
看描述应该是说参数3个但是你给了4个

但是我在super给的参数是三个:a,b,c
 楼主| Paranoid丶 发表于 2021-1-29 11:17
jiangpeng59 发表于 2021-1-29 11:09
D的父类都没有接受3个参数的 __init__方法,肯定会报错啊

所以没有办法接受多个父类的参数吗
boryou 发表于 2021-1-29 12:39
试了下好像class B 里的那个super会调用A的__init__然后还会调用C的__init__,所以报错,原理不知道
另外,为啥用B.__init__(self) 这种方式啊
古月不傲 发表于 2021-1-29 13:03
[Python] 纯文本查看 复制代码
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++的规则一样

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Paranoid丶 + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| Paranoid丶 发表于 2021-1-29 13:43
ufo0033 发表于 2021-1-29 13:20
python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么  b的  super().__init__(a)  实际上 ...

学到了,感谢
古月不傲 发表于 2021-1-29 13:49
ufo0033 发表于 2021-1-29 13:20
python的钻石继承 实际上 是被拉成了线性。从d来看,分别继承b和c 那么  b的  super().__init__(a)  实际上 ...

这种设计牛逼阿,免去了一次构造和析构,不知道C++种有没有这种解决方案
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 04:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表