0

I would like to iterate on distinct functions. I have looked into itertools, and I haven't found anything relevant there. I am looking for something like this:

import mymod
import sys
mymodule= sys.module[__name__]
if __name__ == 'main':
    function_list1=['mymod.f1','mymod.f1(keyword=True)','mymod.f2']
    for func in function_list1:
        try:
            print(getattr(mymod,func)()) # problem: how do I call the keyword
        except Exception, e:
            print(e)
    function_list2=['f1','f2']
    for func in function_list2:
        getattr(mymodule,func)()

I have edited the code, because I want to make explicit that I want to call a function from another module and the current module. And I may want to pass a keyword to the function

module mymod is a collection of functions, it imports some external modules and some modules written by me and then it defines functions that use only local variables

   import sys
   def f1(keyword=False, keyword2='something', keyword3=0.5):
       a = 2
       return a
simona
  • 2,009
  • 6
  • 29
  • 41
  • 1
    Possible duplicate of [Calling a function of a module by using its name (a string)](https://stackoverflow.com/questions/3061/calling-a-function-of-a-module-by-using-its-name-a-string) – Wondercricket Apr 24 '18 at 14:25
  • @Wondercricket how do I call function in the same module? – simona Apr 24 '18 at 14:29
  • 2
    `'mymod.f1'` is not a function (it's a string). `mymod.f1` is perhaps a function, we can't tell from what you posted here. Just getting rid of those single quotes, and using `func()` for the actual call, might allow your code to work. – jasonharper Apr 24 '18 at 14:30
  • @jasonharper you are right, but I would also like to pass keyword sometimes -- I have edited my question – simona Apr 24 '18 at 16:02

2 Answers2

2

I think you are looking for the partial type from functools. In most cases, you don't need it, because functions are first-class object.

from functools import partial
import mymod

if __name__ == '__main__':
    # Functions from another module
    function_list1 = [
        mymod.f1,  # partial(mymod.f1) will work, too.
        partial(mymod.f1, keyword=True),
        mymod.f2
    ]
    for func in function_list1:
        try:
            print(func())
        except Exception, e:
            print(e)

    # Functions from the current module
    function_list2 = [f1, f2]
    for func in function_list2:
        func()
chepner
  • 497,756
  • 71
  • 530
  • 681
1

Use locals or globals.

import mymod
if __name__ == 'main':
    function_list=['mymod.f1','mymod.f2','mymod.f3']
    for func in function_list:
        try:
            locals()[func]() # something here?
        except Exception, e:
            print(e)

or

import mymod
if __name__ == 'main':
    function_list=['mymod.f1','mymod.f2','mymod.f3']
    for func in function_list:
        try:
            globals()[func]() # something here?
        except Exception, e:
            print(e)

this would only work if the functions are in the same module

Also, as said in the comment, you can call the functions directly if you save them without using the inverted commas in the list.

fazkan
  • 352
  • 3
  • 11
  • @fakzan I have edited my question, I would also like to pass keywords sometimes – simona Apr 24 '18 at 15:58
  • @simona can you share mymod with us, I would like to see how the functions are defined in there... – fazkan Apr 24 '18 at 16:34
  • it is a 200 lines file, what do you want to know? – simona Apr 24 '18 at 16:35
  • just show the definitions of mymod.f1, mymod.f2 and mymod.f3, I want to see how they are accepting parameters – fazkan Apr 24 '18 at 16:37
  • by the way if you are calling a function with getattr(mymod,func)(), all you have to do is pass the keyword as it is, so getattr(mymod.func)(keyword=True).... – fazkan Apr 24 '18 at 16:42
  • yes, but what if the keyword depends on the function I am calling? what about if I want to have the keywords with name and value specified in a separate array as strings? – simona Apr 24 '18 at 16:48
  • If possible, store the relevant function name with the relevant key,values, and call call them accordingly. For example, list1 =["keyword", True, "keyword2","notSomething"], you change this list to dictWithFunctions = {"mymod.f1": ["keyword, True], "mymod.f2":["keyword2", "notSomething"]} – fazkan Apr 24 '18 at 16:55
  • what do you mean? also, how do I pass the keywords from the dict to the func? – simona Apr 24 '18 at 16:59
  • 1
    You can pass dynamic keywords to a function, but you will have to restructure your keywords lists into a dict and that might not be worth it. However, in order to explain my thinking you do something like the following. dict_with_funcs = {"mymod.f1": {"keyword":True,"keyword2":"notSomething"}} the dict_with_funcs contains a dicts of the keywords that you want to pass to mymod.f1, then all you do is mymod.f1(**dict_with_funcs["mymod.f1"]) – fazkan Apr 24 '18 at 17:18