Archive
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.
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.
