为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不导致递归错误的情况下在基类中声明子类对象?

如何在不导致递归错误的情况下在基类中声明子类对象?

米琪卡哇伊 2021-06-26 16:18:22
我正在尝试按如下方式构建 Python 3 程序:基类:身体子类:头一个超简单的代码表示如下:class Body:    def __init__(self):        self.head_obj = Head()        # ...Set-up body...    def body_actions:        print('Body does something')class Head(Body):    def __init__(self):        super().__init__()        # ...Set-up head...    def head_actions:        print('Head does something')我希望能够创建一个名为“body_obj”的 Body 实例,然后访问 Head 子类(及其属性/方法),如下所示:body_obj = Body()body_obj.body_actions()body_obj.head_obj.head_actions()但是,当我运行代码时,Python 返回最大递归深度 RuntimeError。我需要在 Body 和 Head 类中使用 __ init __ 进行一些设置,当我不在 Head 类的 __ init __ 中调用 super() 函数时,Pycharm 会抱怨,因为这似乎是不好的做法。建立这种结构的正确方法是什么,在实例化基类时,类的子对象都需要初始化?我已经研究过嵌套类,但这似乎也是不好的做法。
查看完整描述

1 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

头部不是一种身体,它是身体的一部分AFAIK。


所以你应该使用组合而不是继承:


class Head:

    def __init__(self):

        # ...Set-up head...


    def head_actions():

        print('Head does something')


class Body:

    def __init__(self):

        self.head = Head()

        # ...Set-up body...


    def body_actions:

        print('Body does something')

现在你可以这样做:


body = Body()

body.body_actions()

body.head.head_actions()

你得到无限递归的原因是你Body是 的超类Head,所以当你调用super().__init__()你实例化 a 时Body,它在你的实现中创建了 a Head,它调用super().__init__()等等。


组合(如果这就是“嵌套”的意思)不是坏习惯,它是标准做法,通常比继承更有意义。


编辑以回应评论


要从 访问Body方法,Head您可以传递Body对创建时的引用。所以重新定义类如下:


class Head:

    def __init__(self, body):

        self.body = body


    def head_actions():

        print('Head does something')


class Body:

    def __init__(self):

        self.head = Head(self)


    def body_actions:

        print('Body does something')

现在您可以从身体访问头部,从头部访问身体:


body = Body()

head = body.head

head.body.body_actions()

甚至


body.head.body.body_actions()


查看完整回答
反对 回复 2021-06-29
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信