10

What I need is something that gets the variable and if the variable is the name of a function, the function will be called. I am not trying to get a function from a module but from within the program itself

Example:

def foo():
    print("Foo")
callfunction = input("What function do you want to call? ")

callfunction() ## Not sure what to put here but but lets say callfunction is foo.

I don't want something like this because I have many functions:

if callfunction == "Foo"
    Foo()
else:
    print("No function with that name")

My question is something like this, but I ask for the Python syntax. I am using Python 3.5.1

Community
  • 1
  • 1
Fonky44
  • 103
  • 1
  • 1
  • 8

4 Answers4

19

Use a dict mapping names to functions.

call_dict = {
    'foo': foo,
    'bar': bar
}
call_dict[callfunction]()
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
9

You can do this :

eval(input("What function do you want to call? ") + '()')
Jarvis
  • 8,494
  • 3
  • 27
  • 58
  • 3
    This allows the persons using it to execute arbitrary python code (just so long as whatever they do ends with a callable). For example they might just choose to erase all your files. – Duncan Feb 14 '17 at 13:41
  • I am using Python 3.5.1 not 2.7. But this seems to be the easiest solution – Fonky44 Feb 14 '17 at 13:42
  • It is, since you don't use extra variable to store the function name, mark the answer as accepted if it solved your issue. @KalkidanTadesseZewdieBeyene – Jarvis Feb 14 '17 at 13:43
  • @Jarvis i tried it and it worked once but now i always get this TypeError: Callfunction() missing 1 required positional argument: 'event' even after adding event – Fonky44 Feb 14 '17 at 13:57
  • What is your input ? @KalkidanTadesseZewdieBeyene – Jarvis Feb 14 '17 at 13:59
  • @Jarvis def test(event): print("Test") i write test – Fonky44 Feb 14 '17 at 14:02
  • `arg_string = 'test' eval(input("What function do you want to call? ") + '(' + arg_string + ')')` You can take the names of arguments as input as well and append to make comma-separated string - arg_string. – Jarvis Feb 14 '17 at 14:04
  • 4
    @KalkidanTadesseZewdieBeyene: At the first glance this might look like the easiest solution but it's a very very very dangerous solution. Read [Eval really is dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html). – Matthias Feb 14 '17 at 14:36
  • What if we want to call function inside an object? – alper Nov 20 '21 at 13:34
5

It is quite common in Python to use the command pattern. First move all of your functions into a class, and give them names which have a prefix that isn't used in the input. Then use getattr() to find the correct function and call it.

class Commands():
   def cmd_foo(self):
       print("Foo")

   def callFunction(self, name):
       fn = getattr(self, 'cmd_'+name, None)
       if fn is not None:
            fn()

This has a couple of advantages over Daniel's call_dict: you don't have to list the name of the functions a second time, and you don't have to list the callable functions a second time either.

The 'cmd_' prefix is there to ensure you can have other methods in the class but still control exactly which ones are directly callable.

Duncan
  • 92,073
  • 11
  • 122
  • 156
2

This should do it

import inspect
import your_module

list_of_functions = inspect.getmembers(your_module, inspect.isfunction)

Now list_of_functions is a list of tuples with the name of each function at position 0 and the function itself at position 1.

Elmex80s
  • 3,428
  • 1
  • 15
  • 23