Hacker News new | ask | show | jobs
by domnit 6033 days ago
As a dynamic language, Python already has similar tables built in. You can use something like:

  getattr(self, 'handle_%s' % action)
1 comments

If action comes from outside the program, this can open up unexpected behavior. The dispatch table is closed - there's less chance that user input will invoke something unintended.
In a real world program you would validate input and make sure you get something callable (with either technique). The only additional unexpected behavior is when there could be unexpected handle_xxx attributes. If we take for granted that the programmer defines the dict for the explicit dispatch table, though, we can also assume that the programmer defines the object for the implicit table.
IMO as code gets modified by other developers, the table is easier to keep 'safe' since it is clearer that is what it's for, the sprintf and all the other methods don't tend to be in one place - as methods get added, the reflection issue is oft overlooked.
I feel the version from the original comment is most Pythonic. The other version is close to an eval-function, which seems to be frowned up on in Python.
The second version is slower too. Here's what I use for e.g. a state machine, which follows "don't repeat yourself" a little better than the first example:

  # {state_name: state_action}
  states = {}
  
  state = ['start']
  
  def reg(func):
    states[func.__name__] = func
    return func
  
  # define and simultaneously register the states
  @reg
  def start():
    state[0] = 'second'
  
  @reg
  def second():
    state[0] = 'last'
  
  @reg
  def last():
    state[0] = None
  
  
  # run the state machine
  while state[0]:
    print state[0]
    states[state[0]]()
Is the second version slower because the string won't get intern-ed?
Yeah, and the string must be reinterpolated every time (possibly barring some of the more exotic python implementations).
Why are you using mutation?