Python: How to Init a Function by Calling It Using a String

written

This topic is an interesting one that I have faced on a few occasions. There are a couple of different solution that I have found over the last couple of years that work depending on the situation. So let’s back up again and state the problem in the form of a question.

“How do you call a function in python guven a string of the functions name?”

Generally this behavior is not allowed due to the strict type casting of python, ie. a function must be a function type before being able to call. So how do you approach calling a function by using a string? *note that both of these examples are assuming that the functions being called are residing within imported modules.

Here are a couple of examples:

1.) Use the getattr() built-in function to evaluate a module object and provide a string attribute denoting the name of the function to execute. *note This method is generally frowned upon as using getattr and eval are both possibly dangerous built in functions that can lead to security issues / unexpected results.

example:

simple_example
1
2
3
4
5
import foo # Your module

methodCall = getattr(foo, 'bar')

result = methodCall()

2.) You can also write an abstract function capable of evaluating the string provided in a function object, and also evaluate if the function exists in a graceful way. This approach is a bit more complex and makes use of a couple of different modules, along with leveraging decorator functions.

example:

Place this code into a importable module file called registry.py

registry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Registry(object):

  def __init__(self):
    self.funcs = {}

  def execute(self, func):
    self.funcs[func.__name__] = func
    return func

  def dispatch(self, name, *args, **kwargs):
    try:
      return self.funcs[name](*args, **kwargs)
    except Exception as e:
      raise Error(e)

Now create a file that contains your functions you wish to call. In this example call this file myfuncs.py

myfuncs.py
1
2
3
4
5
6
7
import registry

callme = registry.Register()

@callme.execute
def myCoolFunction():
  print 'hello world'

Finally here is the script that will create the string in which we will attempt to execute as a function.

your_script.py
1
2
3
4
5
import myfuncs

runfunc = myfuncs.callme

runfunc.dispatch('myCoolFunction')

As you can see example 2 is quite a bit more involved however can scale to supporting MANY different function template files. This means that you can further abstract your code into a template language to dynamically import with.

Enjoy!