tags:

views:

165

answers:

7

I would like to do something like:

dct = ['do_this', 'do_that']
dct[0]() // call do_this

But you can't call the string as a function (will get an error).

How can I achieve this without switching and without using a list of lambdas or functions?

Explicitly I want to refer the function by name.

+9  A: 

Functions are first-class objects in Python:

def do_this():
    pass

def do_that():
    pass

dct = [do_this, do_that]
dct[0]()  # calls do_this()

If dct absolutely has to be a list of strings, I'd go with eval():

eval(dct[0] + "()")

It's not pretty, but switching between globals() and getattr() on the proper module can be a pain.

Frédéric Hamidi
+7  A: 

Funtions are first class objects. So like this:

def do_this():
    print "In do_this"

def do_that():
    print "In do_that"

dct = [do_this, do_that]
dct[0]()

If you really want to call them from a string list you can use globals():

dct = ['do_this', 'do_that']
globals()[dct[0]]()

But I would suggest that using globals() (or locals()) probably isn't the right way to solve your problem. Grok the python way: >>> import this

kanaka
now it seems obvious, thanks. I prefer your answer to Frédéric's because of the eval part
Alfonso de la Osa
+1  A: 

having the functions in some dict or in a class or instance


def fn_a():
    pass

some_dict = {
    'fn_a': fn_a,
}

class Someclass(object):

  @classmethod
  def fn_a(cls):
    pass

  # normal instance method
  def fn_b(self):
    pass

some_instance = Someclass()

you could do: some_dict['name']() or getattr(some_instance, 'fn_b')() or getattr(Someclass, 'fn_a')()

knitti
+2  A: 

You can use getattr if they are in a module or globals() if they are in the global namespace:

dct = ['do_this', 'do_that']

getattr(my_module, dct[0])()

globals()[dct[0]]()
Zooba
+1  A: 

If the functions you want to call are part of a module:

import module
getattr(module, funcname_string)(*args, **kwargs)
joni
+1  A: 

As others have said, functions in Python are first-class objects. If you really want to get their names from a list, you can either use eval() (not popular) or use the globals() dictionary. Keep in mind that if these strings come from users, they're pretty dangerous. And if they don't come from users, then don't use strings.

Nathon
A: 
def do_this(): pass
def do_that(): pass

dct = dict((x.__name__, x) for x in [do_this, do_that])
# dct maps function names to the function objects
# the names *don't* have to match the function name in your source:
#   dct = {"foo": do_this}
# which means user-facing names can be anything you want

dct["do_this"]()  # call do_this
Roger Pate