0

How to construct and call a function from a string? For example, consider three different functions and a list of strings, I want to be able to use the items in list of strings to construct and call the appropriate function

def do_function1():
    return 'done function1'

def do_function2():
    return 'done function2'

def do_function3():
    return 'done function3'

listOfstr = ['function1','function2','function3']  

for item in listOfstr:
    result = 'do_'+item()
    print(result)

result = 'do_'+item()
TypeError: 'str' object is not callable
DougKruger
  • 4,424
  • 14
  • 41
  • 62
  • 1
    Are you looking for [`eval`](https://docs.python.org/3/library/functions.html#eval)? – UnholySheep Mar 31 '17 at 07:33
  • This similar question might help: [Calling a function of a module from a string with the function's name in Python](http://stackoverflow.com/questions/3061/calling-a-function-of-a-module-from-a-string-with-the-functions-name-in-python) – user2314737 Mar 31 '17 at 07:35
  • can't u just match string to call a function at the place where your return statemnet ends. string x="dosmething." and if(x==do something ){call functions(); or better use switch} – DevKRos Mar 31 '17 at 07:35

3 Answers3

2

The problematic code is

listOfstr = ['function1','function2','function3']  

for item in listOfstr:
    result = 'do_'+item()

In the first loop item, will have the value 'function1'. You are calling this string as if it were a function. But strings are not callable and have no code assigned to them!

Then, you go on with the for loop before doing anything.

Simply refer to item, like this:

for item in listOfstr:
    func_name = 'do_' + item
    func = globals()[func_name]
    func()
phihag
  • 278,196
  • 72
  • 453
  • 469
2

The most explicit way would be to have a dictionary of those functions:

funcs = {
    'function1': do_function1,
    'function2': do_function2,
    'function3': do_function3,
}

funcs[item]()

That way you can also name your functions whatever you want, decouple from item names, make them methods, move to other modules etc without breaking the general design. The other way is globals, as already answered.

bereal
  • 32,519
  • 6
  • 58
  • 104
1

First of all, usually you won't need this. Instead of putting strings in a list, you can also put functions themselves in a list like this:

def do_function1():
    return 'done function1'

def do_function2():
    return 'done function2'

def do_function3():
    return 'done function3'

list_of_functions = [do_function1, do_function2, do_function3]

for item in list_of_functions:
    result = item()
    print(result)

However, if you insist, you can do it like this:

locals()["do_function1"]()

locals() gives you a dictionary of locally defined objects by name.

Ede
  • 387
  • 2
  • 10