GUI Frames and classmethod

Scott David Daniels Scott.Daniels at Acm.Org
Fri Dec 3 17:48:30 EST 2004


Zak Arntson wrote:
> Note the last line. When programming EVERY child I have to remember to
> add this self.create_empty_state_methods() line.
> My question: What are Pythonic alternatives to this sort of thing?
> Now I can't be the first person to want a pre- and post- child init code! 
 > I'm worried that I'm overlooking something or there's an even more
 > Pythonic way to do things than above.

To your explicit question:  The trick is to name the middle part, and
override it you want.  Then your base class can invoke the appropriate
building at the point it likes.

Base frame looks like:

     class BaseFrame(...):
         def __init__(self, ....):
             self.input_state_machine = ...
             # more pre-setup
             self.addrules()
             self.create_empty_states()
             # more post-setup

         def addrules():
             pass

Button (for example) looks like:

     class ButtonFrame(BaseFrame):
         def addrules():
             ism = self.input_state_machine
             ism.add_rule("None", "LWait", (MOUSEBUTTONDOWN, 1))
             ism.add_rule("LWait", "None", (MOUSEBUTTONDOWN, 2))
             ism.add_rule("LWait", "None", (MOUSEBUTTONUP, 1))

See, you needn't even muck with __init__ here, if all you want is
some rules added.  Something which actually wants to do some init stuff:

     class FunkFrame(BaseFrame):
         def __init__(self, ...):
             # more pre-setup
             super(FunkFrame, self).__init__(self, ...)
             # more post-setup

         def addrules():
             self.input_state_machine.add_rule(
                          "None", "RWait", (MOUSEBUTTONDOWN, 1))

 > My current approach is that in the Frame class, I have a method to
 > call _after_ initialization that creates a bunch of dummy methods so
 > the user doesn't have to implement EVERY state change method in a

Really, I think the above is a bad idea.  Don't implement empty
methods.  Make a dictionary of state transitions, and store code in it.
Note: you don't need a dictionary of dictionaries; you could use a
dictionary of pairs.  Do something on each attempted transition like the
following:

     def change_state(self, newstate):
         try:
             action = self.transitions[self.current, newstate]
         except KeyError:
             raise NoRuleError, (self.current, newstate)
             # or pass to ignore missing transitions.
         else:
             action(self)

This method belongs in BaseFrame and assumes a class like:

     class NoRuleError(ValueError):
         def __str__(self):
             return 'No transition defined for %r -> %r' % self.args


--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list