Alternative to multi-line lambdas: Assign-anywhere def statements

Tim Chase python.list at tim.thechases.com
Sat Jan 24 07:23:38 EST 2015


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


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /