Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Problems with super()
#1
Hi, I've been working on a game that requires classes and subclasses. In order to keep some sort of structure, I wanted to put them in different files. Of course with subclasses comes the super() keyword. For single inheritance this does not pose a problem. But when it comes down to multiple inheritance I can't wrap my head around it.

In BaseClasses.py are all the classes most other classes inherit from. The ones in my problem all inherit from Object:
class Object:
    x = 0
    y = 0

    def __init__(self, x, y) -> None:
        self.x = x
        self.y = y
All the visual classes are contained in Shapes.py. The important ones here are Rectangle and its base Shape
class Shape(BaseClasses.Object):
    def __init__(self, x, y) -> None:
        super().__init__(x, y)

class Rectangle(Shape):
    size_x = 0
    size_y = 0
    color = (0, 0, 0)

    def __init__(self, x, y, size_x, size_y, color) -> None:
        super().__init__(x, y)
        self.size_x = size_x
        self.size_y = size_y
        self.color = color
Lastly there's CollisionObjects.py, where the problem occurs.
class Collision_Object(BaseClasses.Object):
    collider_size_x = 0
    collider_size_y = 0

    def __init__(self, x, y, collider_size_x, collider_size_y):
        super().__init__(x, y)
        self.collider_size_x = collider_size_x
        self.collider_size_y = collider_size_y

class Static_Object(Collision_Object, Shapes.Rectangle):
    Color = (255, 0, 0)

    def __init__(self, x, y, size_x, size_y):
        print(Static_Object.__mro__)
        super().__init__(x, y, size_x, size_x)
        super().__init__(x,y, size_x, size_y, self.Color)
I call the Static_Object class from the main game code with the line
StaticObject = CollisionObjects.Static_Object(400, 300, 40, 40)
I've tried a lot of different ways of using super() in the Static_Object class, but none of them seem to work. The way I've got it set up now gives me the following error:
Quote:Exception has occurred: TypeError
Rectangle.__init__() missing 3 required positional arguments: 'size_x', 'size_y', and 'color'
File "C:\Users\Manu Coppieters\Documents\Tomb of the mask\CollisionObjects.py", line 11, in __init__
super().__init__(x, y)
File "C:\Users\Manu Coppieters\Documents\Tomb of the mask\CollisionObjects.py", line 28, in __init__
super().__init__(x, y, size_x, size_x)
File "C:\Users\Manu Coppieters\Documents\Tomb of the mask\Game.py", line 18, in <module>
StaticObject = CollisionObjects.Static_Object(400, 300, 40, 40)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Rectangle.__init__() missing 3 required positional arguments: 'size_x', 'size_y', and 'color'

The weird thing here is that line 11 in CollisionObjects.py is the super().__init__() line in the Collision_Object class. It doesn't inherit from Rectangle, yet it appears to try and initialize it. Writing this out, it makes me think there might be a problem with the MRO?

Anyways, any help is appreciated.
Reply
#2
I think multiple inheritance should be used warily and possibly not at all, an exception being the case of mixin classes.

In your code, the intention behind the classes is not obvious, so it is difficult to give a clear advice. However, remember that inheritance means the ISA relationship, but in your case, I'd tend to believe that the StaticObject is a CollisionObject having a certain shape. Its relation to shape is more HAS-A shape than IS-A shape. If this is true, you could replace inheritance with composition, which is usually considered a better design. So you would write the class as
class StaticObject(Collision_Object):
    Color = (255, 0, 0)
 
    def __init__(self, x, y, size_x, size_y):
        print(Static_Object.__mro__)
        super().__init__(x, y, size_x, size_x)
        self.shape = Shapes.Rectangle(x,y, size_x, size_y, self.Color)
If you insist on using multiple inheritance, you could do this for example
class StaticObject(CollisionObject, Shapes.Rectangle):
    Color = (255, 0, 0)
 
    def __init__(self, x, y, size_x, size_y):
        print(StaticObject.__mro__)
        super().__init__(x, y, size_x, size_x)
        Shapes.Rectangle.__init__(self, x,y, size_x, size_y, self.Color)
Also have a look at PEP8 with regards to class naming conventions. Of course, PEP8 is not mandatory.
« We can solve any problem by introducing an extra level of indirection »
Reply
#3
(Apr-10-2024, 08:39 AM)Gribouillis Wrote: I think multiple inheritance should be used warily and possibly not at all, an exception being the case of mixin classes.

In your code, the intention behind the classes is not obvious, so it is difficult to give a clear advice. However, remember that inheritance means the ISA relationship, but in your case, I'd tend to believe that the StaticObject is a CollisionObject having a certain shape. Its relation to shape is more HAS-A shape than IS-A shape. If this is true, you could replace inheritance with composition, which is usually considered a better design...

Thank you for your reply. I originally structured my code with IS-A relations, but in the example code my professor gave me there were a lot of HAS-A relations, hence why I changed it. I think I will revert my code back to the IS-A relations I used to have.

Thank you for your help!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  super() in class akbarza 1 509 Dec-19-2023, 12:55 PM
Last Post: menator01
  superclass and super() grkiran2011 1 1,779 Jun-20-2020, 04:37 AM
Last Post: deanhystad
  MRO About super() catlessness 1 2,088 Jan-12-2020, 07:54 AM
Last Post: Gribouillis
  Super with Sublime Text - TypeError: super() takes at least 1 argument (0 given) Shafla 6 7,548 May-04-2019, 08:30 PM
Last Post: Shafla
  Is any super keyword like java rajeev1729 2 3,360 Sep-14-2017, 07:47 PM
Last Post: snippsat
  Multiple Inheritance using super() Sagar 2 7,347 Sep-08-2017, 08:58 AM
Last Post: Sagar

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020