18

I want to store functions in a list and then later in a program call those functions from that list.

This works for me, however, I don't know if it is correct :

#example functions, my functions would actually get user input etc.
def func1():
    return 2
def func2():
    return 3

options = [ func1, func2 ]

#call functions

options[0]()

Is this the proper way to store functions in a list and call it ? Or is there a different, better way to do this?

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
Davlog
  • 2,162
  • 8
  • 36
  • 60
  • 7
    This way is perfectly fine – inspectorG4dget Dec 14 '14 at 18:44
  • Why you store functions in a list at the first place? You can call them whenever you want without them store in a list. – GLHF Dec 14 '14 at 18:45
  • 4
    That seems fine to me. Of course, you will need to remember the order of the functions in the list. Otherwise, you may want to use a dictionary and access the function objects by name: `options = {'func1':func1, 'func2':func2}; options['func1']()`. But then you have to ask yourself why you are doing this in the first place. You could just put the functions in a module and import that instead. –  Dec 14 '14 at 18:46
  • Thanks, I wasnt sure. Never seen something like this and all I did was just experimenting and guessing. I dont want it to cause future problems in my program cause I dont know if this is safe / actually working etc. – Davlog Dec 14 '14 at 18:46
  • @qqvc because this is actually code reducing and easier to modify in my case. I get user input (a number) and now I only have to make sure the index is valid and call the function from that list by index. Otherwise I would have to create a huge if block. That is messy, ugly and a lot of code. You know what I mean? – Davlog Dec 14 '14 at 18:53
  • @GLHF, I also think in some works this is necessary (other ways may also do). I need to optimize few parameters inside 20 functions that have different parameters. I am also thinking of putting the functions with params in a list. – Prasanta Bandyopadhyay Mar 28 '22 at 05:55
  • Hello, can such functions through `self` in the parameter-list be called in the context of a class and hence access instance-variables and other instance-functions ? Respectively class-things through `cls` in the param-list. Thanks. – von spotz Feb 20 '23 at 17:40

3 Answers3

9

Yes, you can do it. If you want to call all functions in the list with a "one liner" you can do the following:

results = [f() for f in options]
code monkey
  • 2,094
  • 3
  • 23
  • 26
6

Yes, this is correct, though if your functions are really one-liner in nature, I would suggest you also have a look at lambdas, so that your entire code can be reduced to:

options = [lambda: 3, lambda: 2]

As already pointed out in comments, you will of course need to remember the order of the functions in the list.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
1

I like to do things like

class Commander:
    def CommandERROR(*args, **kwargs):
        print "Invalid command"

    def CommandFunc1(*args, **kwargs):
        print "Do Command 1"

    def CommandFunc2(*args, **kwargs):
        print "Do Command 2"

    def CallCommand(command, *args,**kwargs):
        self.__dict__.get("Command"+command, self.CommandError)(*args, **kwargs)
    
    
cmd = Commander()
cmd.CallCommand("Func1", "arg1", something=5)
cmd.CallCommand("Func2", "arg2", something=12)
cmd.CallCommand("Nothing", "arg1", something=5)

as pointed out in the comments you can also put this in its own file to create the namespace and ommit the class ... although if you need to affect state then maybe a class is a better option ... you could also use a simple dict

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 3
    There is not really a reason to create a class if you do not need to maintain state or use any special methods. If you simply need a namespace, use a module. –  Dec 14 '14 at 18:55
  • @iCodez ... I agree ... but its easier to show a class for namespace in stack overflow answers – Joran Beasley Dec 14 '14 at 18:56
  • What's the point of `CommandERROR` when you could just let the `KeyError` propagate? And why are you using `self.__dict__.get(...)` when you could use `getattr(self, ...)`? – wjandrea Mar 13 '23 at 20:00