class Menu: # the menu superclass def __getattr__(self, name): # pass off to 'menu' return getattr(self.menu, name) # keys, append, sort... def run(self, prompt='?'): try: while 1: # common interactive loop print '\n\tMENU...' self.showOptions() command = raw_input(prompt) try: flag = self.runCommand(command) except (IndexError, KeyError): print "what: '%s'?" % command else: if flag: break except EOFError: pass # ctrl-d still exits all class DictMenu(Menu): # a Menu subclass def __add__(self, other): new = DictMenu() # make a new instance new.menu = {} for key in self.menu.keys(): new.menu[key] = self.menu[key] # copy 'self' dict for key in other.keys(): new.menu[key] = other[key] # add other dict return new def showOptions(self): options = self.menu.keys() # menu = mapping options.sort() for cmd in options: print '\t\t' + cmd def runCommand(self, cmd): return self.menu[cmd]() # call method/function class ListMenu(Menu): # menu = nested sequences def __add__(self, other): new = ListMenu() # make a new instance new.menu = self.menu + other # copy 'self' list return new # add other list def showOptions(self): for i in range(len(self.menu)): print '\t\t%d) %s' % (i, self.menu[i][0]) def runCommand(self, cmd): try: index = eval(cmd) # convert string to number except: raise IndexError return self.menu[index][1]() # selected by number