call a function by knowing its name as a string
Problem
I want to call a function but its name is stored in a string. How to do that?
Solution
I wanted to create a menu where the user can select which entry to call. It looks like this:
(1)[r] radio (2)[ctd] create temp. directory -------- [m] menu [q] <
In Python I stored it like this:
menu = OrderedDict() menu[(1, 'r')] = ('radio', 'apps.radio.radio_player') menu[(2, 'ctd')] = ('create temp. directory', 'apps.temp_folder.create_temp_folder')
That is, if the user selects “1
“, then apps.radio.radio_player()
must be called.
Here is the method that can call the appropriate function:
import importlib def start_app(val): """ Call a function by name (string). Tip from here: http://stackoverflow.com/questions/3061 . """ _, to_call = val function_string = to_call # ex.: 'apps.radio.radio_player' mod_name, func_name = function_string.rsplit('.', 1) mod = importlib.import_module(mod_name) func = getattr(mod, func_name) func()
The tip is from here.
Useful Python modules
Creating and importing a module
If you have some functions that you use often, you can collect them in a module.
mymodule.py
:
def f1(n): return n + 1
How to use it (use-mymodule.py
):
#!/usr/bin/env python import mymodule print mymodule.f1(5) # => 6 print mymodule.__name__ # => mymodule (note that .py is missing)
It is also possible to add some testing code to a module:
mymodule.py
:
#!/usr/bin/env python def f1(n): return n + 1 if __name__ == "__main__": number = 1977 print f1(number) # => 1978
Now, you can still import it like in use-mymodule.py
, or you can launch it as if it were a standalone script. In the latter case the test suite will be executed. If you import it, the test suite is not executed. A test suite is a good practice to be sure that the module is working as expected.