So I’m making a game, and all objects derive from one GameObject class, which looks something like this;
class GameObject(pygame.sprite.DirtySprite):
actions = dict()
def __init__(self):
pygame.sprite.DirtySprite.__init__(self)
self.rect = None
self.state = None
def update(self):
if callable(self.__class__.actions[self.state]):
#If this key has a function for its element...
self.__class__.actions[self.state](self)
Now, I’m running into another issue with inheritance. Observe the class below, and the two that derive from it;
class Bullet(gameobject.GameObject):
FRAME = pygame.Rect(23, 5, 5, 5)
STATES = config.Enum('IDLE', 'FIRED', 'MOVING', 'RESET')
def __init__(self):
gameobject.GameObject.__init__(self)
self.image = config.SPRITES.subsurface(self.__class__.FRAME)
self.rect = self.__class__.START_POS.copy()
self.state = self.__class__.STATES.IDLE
actions = {
STATES.IDLE : None ,
STATES.FIRED : start_moving,
STATES.MOVING : move ,
STATES.RESET : reset ,
}
class ShipBullet(bullet.Bullet):
SPEED = -8
START_POS = pygame.Rect('something')
def __init__(self):
super(self.__class__, self).__init__()
self.add(ingame.PLAYER)
class EnemyBullet(bullet.Bullet):
SPEED = 2
START_POS = pygame.Rect('something else')
def __init__(self):
super(self.__class__, self).__init__()
self.add(ingame.ENEMIES)
Every element of Bullet.actions (a static member, mind you) except for None is a function held within Bullet. Bullet is not meant to be created on its own; if this were C++, it would be an abstract class. So what happens is, Bullet‘s subclasses search through Bullet.actions every frame to decide what to do next, depending on their state (are they moving, were they just shot, etc.). However, since the elements of Bullet.actions are Bullet‘s own methods, its subclasses are executing those instead of their own extended versions (which call the parent methods). I don’t want to have to duplicate this dict of callbacks for memory usage reasons. So, I ask this; how can I have an instance of a subclass look through it’s parents dictionary full of callback methods, and execute their own version if it exists, and their parent’s version if it doesn’t?
One possible solution is to store the function’s name instead of direct references and using
getattrto retrieve the correct reference:For a speedup, you can pre-compute this table when initializing the object:
Notice that since the code in
__init__usesgetattr, it can be placed inBullet.__init__and merely extended by the other classes. As you already call the super constructor, there would be no need to change the extending classes or even annotate them.