Python:难以从多个父类继承

时间:2018-07-12 20:54:45

标签: python class oop

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

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):

KineticBall

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

KineticBouncing

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)

ball => 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 Multiple Inheritance可以解决我的问题。只需使用父母的名字+ init 代替super()对吧?

KineticBouncing

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)

ball => 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)

那么我应该怎么继承这两个父类呢?

2 个答案:

答案 0 :(得分:0)

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

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

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

我相信您希望此呼叫Ball.__init__super的工作方式并非如此。而是根据对象super解析KineticBouncing。那么... superKineticBouncing是什么?请注意,在编写两个__init__调用之间,您必须至少一次出错。

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

答案 1 :(得分:0)

在您父母的所有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
相关问题