Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: dispatch method with string input

Tags:

python

I need to write a method that takes in 3 arguments:

  1. a string with the name of a function
  2. an ordered list of arguments to that function. This includes arguments with default values and *varargs, but does not include **kwargs
  3. a dict representing any additional keyword arguments, or None if there are none

And I need to use this input to retrieve a function and call it. For example:

def dispatch(name, args, kwargs=None):
    do_magic_here(name, args, kwargs)

def meth1():
    print "meth1"

def meth2(a, b):
    print "meth2: %s %s" % (a, b)

def meth3(a, **kwargs):
    print "meth3: " + a
    for k,v in kwargs.iteritems():
        print "%s: %s" % (k,v)

And I need to be able to call things like this:

>>> dispatch("meth1", [])
meth1
>>> dispatch("meth2", [1, 3])
meth2: 1 3
>>> dispatch("meth3", [1], {"hello":2, "there":3})
meth3: 1
hello: 2
there: 3

I could do this:

def do_magic_here(name, args, kwargs=None):
    if name=="meth1":
        meth1()
    if name=="meth2":
        meth2(args[0], args[1])
    if name=="meth3":
        meth3(args[0], **kwargs)

But I'm trying to dispatch like 40 methods, and that number may expand, so I'm hoping there's a more programmatic way to do it. I'm looking at something with getattr, but I can't quite figure it out.

like image 399
ewok Avatar asked Mar 12 '23 18:03

ewok


1 Answers

I would just use

def dispatch(name, *args, **kwargs):
    func_name_dict[name](*args, **kwargs)

with

func_name_dict = {'meth1':meth1,
                  'meth2':meth2,
                  ...}

Allowing you to pass args and kwargs through more naturally and transparently:

>>> dispatch("meth2", 1, 3)
meth2: 1 3

You can of course use globals() or locals() in place of the dict, but you might need to be careful about which functions in each namespace you do or don't want to expose to the caller

like image 58
DaveBensonPhillips Avatar answered Mar 30 '23 00:03

DaveBensonPhillips