It can be broken if someone tries to use the class as is - that is treating the class as a model - to drive a display of the ship. If it was written using super() then that wouldn't be a problem.
For example, I could write a display mixin that I'd like to use like this: class VisibleShip(ship, sprite): ... and class FasterVisibleShip(faster_ship, sprite): ... But because neither ship nor faster_ship call their super class correctly, this won't work. To turn this into something concrete, consider the following code: class mixin(object): """ The key benefit of this mixin is that it tracks instances created and also allows subclasses to have inheritable default values. """ objects = [] def __init__(self, **kwargs): super(mixin, self).__init__() self.__dict__.update(**kwargs) self.objects.append(self) Using that code, I can create my ship model as a mixin: class ship(mixin): x = 0 y = 0 step = 1 angle = 0 name = "" def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step self.y = self.y + math.sin(math.radians(self.angle)) * self.step As well as the faster ship: class fastership(ship): speed = 1 def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step * self.speed self.y = self.y + math.sin(math.radians(self.angle)) * self.step * self.speed I can then create a sprite mixin: class sprite(mixin): x = 0 y = 0 image = "sprite.png" display = None def __init__(self, **kwargs): super(sprite, self).__init__(**kwargs) self._image = pygame.image.load(self.image) print "Image Loaded", self.__class__ def render(self,surface): # assume surface is something like a pygame surface surface.blit(self._image, (self.x, self.y)) And also for debug purposes a debug mixin: import time class debug(mixin): debug_file = "debug.log" debug_handle = None def __init__(self, **kwargs): print "Creation arguments", self.__class__, kwargs super(debug, self).__init__(**kwargs) @classmethod def dump_state(klass,self): if klass.debug_handle is None: klass.debug_handle = open(self.debug_file, "w") klass.debug_handle.write(str(time.time()) + ":" + str(klass) + ":" + str(self.__dict__)+"\n\n") klass.debug_handle.flush() Using these we can create visible ships which can also send debug information to a file when they're pinged: class VisibleShip(ship, sprite, debug): x = 300 y = 300 image = "ship.png" class FasterVisibleShip(fastership, sprite, debug): x = 400 y = 400 image = "fastship.png" And use them like this: import pygame pygame.init() display = pygame.display.set_mode((800, 600), 0) ship_one = VisibleShip(step=1) ship_two = FasterVisibleShip(angle = 60) t = time.time() while time.time()-t <1 : display.fill((0,0,0)) for sprite in mixin.objects: sprite.render(display) sprite.dump_state(sprite) sprite.update() pygame.display.flip() time.sleep(0.05) Now, you could do this the other way I mentioned by by using kwargs, and super in this way you can get the various classes to play nicely with each other, which means you can have clearer code. After all, our ship / fastership have now become focussed on the code you want them to model - not on faff with superclasses: class ship(mixin): x = 0 y = 0 step = 1 angle = 0 name = "" def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step self.y = self.y + math.sin(math.radians(self.angle)) * self.step class fastership(ship): speed = 1 def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step * self.speed self.y = self.y + math.sin(math.radians(self.angle)) * self.step * self.speed But not only that they play nicely with debug code and also display code, and you get defaults you can inherit at the same time too. If you wrote ship / fastership with an explicit init and didn't do the super() call - eg like this: class ship(object): def __init__(self,x=0,y=0,step=1,angle=0, name=''): self.x = x self.y = y self.step = step self.angle = angle self.name = name def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step self.y = self.y + math.sin(math.radians(self.angle)) * self.step class fastership(ship): def __init__(self,speed=1): ship.__init__(self,x=0,y=0,step=1,angle=0, name='') self.speed = speed def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step * self.speed self.y = self.y + math.sin(math.radians(self.angle)) * self.step * self.speed and mixed in like this: class VisibleShip(ship, sprite): image = "ship.png" class FasterVisibleShip(fastership, sprite): image = "fastship.png" Then the code breaks - simply because you're doing this: ship.__init__(self,x=0,y=0,step=1,angle=0, name='') rather than: super(ship,self).__init__() and super(fastership,self).__init__() At the end of the day, both approaches *work* but to differing levels and differing levels of flexibility & maintainability. >From the perspective of fragility though this approach is far more fragile: ship.__init__(self,x=0,y=0,step=1,angle=0, name='') </tuppenceworth> For convenience I'm copying below my .sig the code I mention above, for you to make your own mind up which you find more maintainable. (Consider extending sprite handling, or the complexity of the ship model) Michael. -- http://www.kamaelia.org/Home , http://twitter.com/kamaelian #!/usr/bin/python class mixin(object): """ The key benefit of this mixin is that it tracks instances created and also allows subclasses to have inheritable default values. """ objects = [] def __init__(self, **kwargs): super(mixin, self).__init__() self.__dict__.update(**kwargs) self.objects.append(self) import math class ship(mixin): x = 0 y = 0 step = 1 angle = 0 name = "" def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step self.y = self.y + math.sin(math.radians(self.angle)) * self.step class fastership(ship): speed = 1 def update(self): self.x = self.x + math.cos(math.radians(self.angle)) * self.step * self.speed self.y = self.y + math.sin(math.radians(self.angle)) * self.step * self.speed class sprite(mixin): x = 0 y = 0 image = "sprite.png" display = None def __init__(self, **kwargs): super(sprite, self).__init__(**kwargs) self._image = pygame.image.load(self.image) print "Image Loaded", self.__class__ def render(self,surface): # assume surface is something like a pygame surface surface.blit(self._image, (self.x, self.y)) import time class debug(mixin): "Not perfect at all IMO" debug_file = "debug.log" debug_handle = None def __init__(self, **kwargs): print "Creation arguments", self.__class__, kwargs super(debug, self).__init__(**kwargs) @classmethod def dump_state(klass,self): if klass.debug_handle is None: klass.debug_handle = open(self.debug_file, "w") klass.debug_handle.write(str(time.time()) + ":" + str(klass) + ":" + str(self.__dict__)+"\n\n") klass.debug_handle.flush() class VisibleShip(ship, sprite, debug): x = 300 y = 300 image = "ship.png" class FasterVisibleShip(fastership, sprite, debug): x = 400 y = 400 image = "fastship.png" import pygame pygame.init() display = pygame.display.set_mode((800, 600), 0) ship_one = VisibleShip(step=1) ship_two = FasterVisibleShip(angle = 60) t = time.time() while time.time()-t <1 : display.fill((0,0,0)) for sprite in mixin.objects: sprite.render(display) sprite.dump_state(sprite) sprite.update() pygame.display.flip() time.sleep(0.05) -- http://mail.python.org/mailman/listinfo/python-list