call function of class instance with no assigned name?

Aaron Brady castironpi at gmail.com
Tue May 5 22:16:39 CEST 2009


On May 5, 2:17 pm, George Oliver <georgeolive... at gmail.com> wrote:
> On May 5, 11:59 am, Dave Angel <da... at ieee.org> wrote:
>
> > 1) forget about getattr() unless you have hundreds of methods in your
> > map.  The real question is why you need two maps. What good is the
> > "command string" doing you?   Why not just map the keyvalues directly
> > into function objects?
>
> Thanks for the reply Dave. I understand your example and it's what I
> originally used. Here is more detail on what I'm doing now, I hope
> this will explain my question better.
>
> In the game I'm writing the player, monsters, items and so on are
> instances of class Thing, like:
>
> class Thing(object):
>     def __init__(self, x, y, name):
>         self.x, self.y = x, y
>         self.name = name
>         self.brain = None
>
> Some Things have an instance of class Brain attached. The Brain
> instance has a list of handlers, like:
>
> class Brain(object):
>     def __init__(self):
>         self.handlers = []
>
> A handler class defines some functionality for the Brain. Each Brain
> has an update method like this:
>
> def update(self, arguments):
>     for handler in self.handlers:
>         handler.update(arguments)
>
> So on each pass through the main game loop, it calls the update method
> of all the brains in the game, which run their handler update methods
> to change the state of the game.
>
> A handler would be something like a key input handler. The key input
> handler is defined separately from the command handler in the case I
> want to use a different method of input, for example a mouse or
> joystick.
>
> In the dictionary of key inputs I could map each input directly to a
> function. However there is no instance name I can call the function
> on, as I create a thing, add a brain, and add handlers to the brain
> like this:
>
> player = Thing(26, 16, 'player')
> player.brain = Brain()
> player.brain.add_handlers(
>                             commandHandler(player.brain, player),
>                             keyboardHandler(player.brain),
>                             fovHandler(player.brain))
>
> So what I'm wondering is how to reference the instance in each brain's
> list of handlers when I want to map something like a key input to a
> command, or what a better way might be to structure the code.

I'm not entirely sure I follow, but you may want to try keeping a set
(or list) of handlers that you pass in to the 'add_handlers' function,
and trying the 'getattr( handlerX, keyY )' on each of them, possible
only until you have a success.  You could also cache these results to
avoid performing the same search subsequently.

Otherwise, query each of the passed-in handlers when they are passed
in for a list of events they can handle; this may be by a brute
'getattr( x ) for x in ALL_EVENTS', or by maintaining a list of
handlers on a per-object basis, and merely combining the dictionaries;
then pick one or all of the handlers you've accumulated for an event
when the event occurs.

</run-on sentence>

If you're really trying to be clever, you might use a metaclass or
class decorator to accumulate what events are handled in a class; or
just try the '__dict__' member of the /class/.

Will any of your handlers be handling overlapping or duplicate
events?  Do they all get a crack at it, or do you follow a pre-
deterimend order of precedence, or follow the order in which they were
passed in?

I'd probably try to discourage you from circularly linking the object
and handlers, not only for practical reasons.

There is also the possibility you could use dynamic mix-ins to create
a specialized once-in-a-lifetime brain class:

def create_brain( handlers ):
    class new_brain( Brain ):
        pass
    for x in handlers:
        setattr( new_brain, x.__name__, x )
    return new_brain

brain= create_brain( handlers )( creation_args )

Forgive, just Thing-king aloud.



More information about the Python-list mailing list