On 2015-01-24 17:28, Chris Angelico wrote: > but this is hardly generic. There's no convenient way to give an > argument to a decorator that says "please assign this here", short > of using some stupid eval hack... is there? > > (Incidentally, for a non-generic dispatch table, a callable dict > subclass could be pretty clean: > > class DispatchTable(dict): > """Self-populating dictionary - use this as a function decorator > to stuff functions into it.""" > def __call__(self, func): > self[func.__name__] = func > return func > > cmd = DispatchTable() > > @cmd > def foo(*args): > print("You asked to foo.")
As best I can tell, your question is "is there a better way to do dispatch tables without duplicating the storage location while remaining sufficiently generic?" The closest I've seen is something like cmd.Cmd does where you have a class and dispatch methods on it with a certain naming convention (this prevents odd access to dunder methods). Akin to your first example [reordered from your original post] > cmd = {} # Command dispatch table > > def cmd["foo"](*args): > print("You asked to foo.") > > def cmd["bar"](*args): > print("There's no wine in the bar.") > > def cmd["asdf"](*args): > print("Asdf! Asdf!") It usually looks something like class Dispatcher(object): def __getitem__(self, name): return getattr(self, "do_" + name) class MyExample(Dispatcher): def do_hello(self, who): print("Hello, %s" % who) def do_goodbye(self, who, feeling): print("Goodbye, %s. I'm %s to see you go" % ( who, feeling)) mydispatch = MyExample() mydispatch["hello"]("world") mydispatch["goodbye"]("cruel world", "sorry") mydispatch["does not exist"]("give me an AttributeError") The root Dispatcher object can grow helpful methods like class Dispatcher(object): # ... def get_help(self, name): return getattr(self, name, "No help for %r" % name) def __iter__(self): for name in dir(self): if name.startswith("do_") and callable(getattr(self, "do_" + name)): yield name # ... def do_hello(self, who): "Say hello to a person" # ... # print out all known methods and their help for method in mydispatch: print("%s: %s" % (method, mydispatch.get_help(method_name))) -tkc -- https://mail.python.org/mailman/listinfo/python-list