繁体   English   中英

Python:从多个父类继承有麻烦

[英]Python: trouble inheriting from multiple parent classes

我有一个子类,需要从两个父类继承,这些父类仅在方法和单个属性上有所不同。 实例化此类时,我收到一条错误消息,指出我正在使用许多参数。 删除参数时,提示我使用不足。

class Ball:
    """
    base class for bouncing objects
    """
    def __init__(self, bounds, position, velocity, color, radius):
        self.position = position
        self.velocity = velocity
        self.bounds = bounds
        self.color = color
        self.radius = radius

    def update(self):
        # bounce at edges.  TODO: Fix sticky edges
        if self.position.x < 0 + self.radius or self.position.x > self.bounds[0] - self.radius: # screen width
            self.velocity.x *= -1
        if self.position.y < 0 + self.radius or self.position.y > self.bounds[1] - self.radius: # screen height
            self.velocity.y *= -1
        self.position += self.velocity

    def draw(self, screen, pygame):
        # cast x and y to int for drawing
        pygame.draw.circle(screen, self.color, [int(self.position.x), int(self.position.y)], self.radius)

弹跳球

class BouncingBall(Ball):
    """
    ball effected by gravity
    """
    def __init__(self, bounds, position, velocity, color, radius, weight):
        super().__init__(bounds, position, velocity, color, radius)
        self.weight = weight

    def update(self):

动力学球

class KineticBall(Ball):
    """
    A ball that collides with other collidable balls using simple elastic circle collision
    """
    def __init__(self, bounds, position, velocity, color, radius, object_list):
        super().__init__(bounds, position, velocity, color, radius)
        self.object_list = object_list

动弹跳动

class KineticBouncing(BouncingBall, KineticBall):
    def __init__(self, bounds, position, velocity, color, radius, weight, object_list):
        super().__init__(bounds, position, velocity, color, radius, weight, object_list)

球=> KineticBouncing

# super().__init__(bounds, position, velocity, color, radius, weight, object_list)
TypeError: __init__() takes 7 positional arguments but 8 were given

ball = KineticBouncing(SCREEN_SIZE, Vector2(50, 50), Vector2(3, 3), [255, 0, 255], 10, -1, object_list)

让我们尝试其他...

所以这令人困惑..相反,我找到了Python3多重继承 ,我相信它将解决我的问题。 只需使用父母的名字+ init代替super()吧?

动弹跳动

class KineticBouncing(BouncingBall, KineticBall):
    def __init__(self, bounds, position, velocity, color, radius, weight, object_list):
        BouncingBall.__init__(self, bounds, position, velocity, color, radius, weight)
        KineticBall.__init__(self, bounds, position, velocity, color, radius, object_list)

球=> KinetBouncing

#Traceback (most recent call last):
#  File "draw.py", line 99, in <module>
#    main()
#  File "draw.py", line 61, in main
#    debug_create_balls(object_list)
#  File "draw.py", line 43, in debug_create_balls
#    ball = KineticBouncing(SCREEN_SIZE, Vector2(50, 50), Vector2(3, 3), [255, 0, 255], 10, -1, object_list)
#  File "/home/adam/Desktop/web_dev/lambda_school/python/Python-OOP-Toy/src/ball.py", line 115, in __init__
#    BouncingBall.__init__(self, bounds, position, velocity, color, radius, weight)
#  File "/home/adam/Desktop/web_dev/lambda_school/python/Python-OOP-Toy/src/ball.py", line 33, in __init__
#    super().__init__(bounds, position, velocity, color, radius)
#TypeError: __init__() missing 1 required positional argument: 'object_list'

ball = KineticBouncing(SCREEN_SIZE, Vector2(50, 50), Vector2(3, 3), [255, 0, 255], 10, -1, object_list)

那么,我该如何继承这两个父类呢?

正如其他人指出的那样,您应该稍微重新设计类的使用。 直接的问题是super()解析为所讨论对象的第一个父类( self ),而不是您当时所使用的__init__方法的父类。

当您尝试初始化KineticBouncing对象时,将调用KineticBouncing.super().__init__() 这将显式调用其两个父类的__init__方法。 当它第一次在BouncingBall调用它时,第一个活动语句是

    super().__init__(bounds, position, velocity, color, radius)

我相信您希望这能称呼Ball.__init__ ; super不是这样的。 相反,它基于KineticBouncing类的对象来解析super 那么...什么是KineticBouncing super KineticBouncing 请注意,在编写两个__init__调用之间,您必须至少犯错一次。

我将让您阅读评论中提供的链接。 这些将帮助您考虑Python的继承结构。 有了您发布的内容,我认为您在处理此开关方面会很轻松; 您只是从其他地方选择了层次结构模型。

在您父母的所有init中使用*args

class Ball(object):
    def __init__(self, *args):
        print ('IN Ball')

class BouncingBall(Ball):
    """
    ball effected by gravity
    """ 
    def __init__(self, bounds, position, velocity, color, radius, weight, *args):
        print ('IN BouncingBall')
        super().__init__(bounds, position, velocity, color, radius, *args)
        self.weight = weight

class KineticBall(Ball):
    """
    A ball that collides with other collidable balls using simple elastic circle collision
    """ 
    def __init__(self, bounds, position, velocity, color, radius, object_list, *args):
        print ('IN KineticBall') 
        super().__init__(bounds, position, velocity, color, radius, *args)
        self.object_list = object_list

class KineticBouncing(BouncingBall, KineticBall):
    def __init__(self, bounds, position, velocity, color, radius, weight, object_list):
        print ('IN KineticBouncing')
        super().__init__(bounds, position, velocity, color, radius, weight, object_list)

现在创建一个新的动力弹跳球

ball = KineticBouncing('SCREEN_SIZE', 'Vector2(50, 50)', 'Vector2(3, 3)', [255, 0, 255], 10, -1, 'object_list')
IN KineticBouncing
IN BouncingBall
IN KineticBall
IN Ball

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM