-3

I have a list of functions and need to call a function, if that function exists in that list. Also, I need to call the function with a string.

I have tried doing something like this:

if "func1" in funcs:
    funcs.__getitem__("func1")

but I can't get it right

funcs = [func1, func2, func3]

def func1: return 1
def func2: return 2
def func3: return 3

if "func1" in funcs:
    # call func1 since it exists

I expect the output to be 1, but I don't know how to call the function. Also, this is not a duplicate because I won't call the function from a class.

roguemacro
  • 199
  • 2
  • 16
  • 1
    Possible duplicate of [Python: call a function from string name](https://stackoverflow.com/questions/7936572/python-call-a-function-from-string-name) – TrebledJ Jun 08 '19 at 20:21

5 Answers5

3

Found out that I'll just use a dictionary instead. Much easier.

funcs = {"func1": func1, etc..}

def func1(): return 1
def etc..

if "func1" in funcs:
    funcs["funcs1"]()
roguemacro
  • 199
  • 2
  • 16
  • `locals()` and `globals()` already provide a dictionary, albeit with additional dunders. – TrebledJ Jun 08 '19 at 20:19
  • 1
    @TrebledJ indeed, which is why it would be bad form recommending or mentioning them in the context here. It's a worse option over using your own dictionaries specifically for mapping strings to your own functions to expose to the end user. (Let's see what mess they can create if given access to globals. ?) – Paritosh Singh Jun 08 '19 at 20:22
  • I used `globals()` in my new solution. – Gwang-Jin Kim Jun 08 '19 at 20:52
  • If you think that this is a better solution, you might want to accept it (the green checkmark) instead of the other answer. – JJJ Jun 09 '19 at 08:43
0

You can also use the class structure and the inspect module which might provide a bit more flexibility:

import inspect
class funcs:
    def func1(): return 1
    def func2(): return 2
    def func3(): return 3

listfuncs = inspect.getmembers(funcs, lambda a:inspect.isfunction(a))

print(listfuncs)

listfuncs will be a list of tuples with function names and object reference.

rroutsong
  • 45
  • 5
0

Just improvising on the answer already provided by @Gwang-Jin Kim.

What happens if you do it this way?

def func1():
    return 1

def func2():
    return 2


tuple_list = [("func1",func1), ("func2", func2)]


if any([items[0] == "func1" for items in tuple_list]):
    print("Do Something")

or this

for key, val in tuple_list:
    if key == "func1":
        print(val())

Also, it seems like a repeated question of call list of function using list comprehension

coldy
  • 2,115
  • 2
  • 17
  • 28
0

Gwang-Jin Kim is right in the fact that Python is interpreted; therefore, you functions needs to be defined before they are called. Now, you need to call a function when the user types the name of that function. It is possible to run the text that the user types with the eval() function; however, that is not recommended, because one cannot be sure of what the user will type in, which could result in unwanted errors.

Instead I recommend that you use a command system, where you call a function based on a predefined name, like shown:

def func1():
    print(1)


def func2():
    print(2)


while True:
    try:
        msg = input('Which function would you like to call?: ')

        if not msg:
            break

        if msg.startswith('func1'):
            func1()

        if msg.startswith('func2'):
            func2()
    except Exception as e:
        print(e)
        break
-3
def func1(): return 1
def func2(): return 2
def func3(): return 3

funcs = [func1, func2, func3]
funcs_dict = {f.__name__: f for f in funcs}

funcname = "func1"

funcs_dict[funcname]()

This checks - if functionname is under the functions name in funcs, then executes it!

(One can use dictionaries in Python to avoid if-checkings).

In case, that there are not such a list like funcs given, one has to do it using globals():

if callable(globals()[funcname]):
    print(globals()[funcname]())

if callable(eval(funcname)):
    print(eval(funcname)())

or:

try:
    print(eval(funcname)())
except:
    print("No such functionname: {}".format(funcname))

or:

try:
    globals()[funcname]()
except:
    print("No such functionname: {}".format(funcname))
Gwang-Jin Kim
  • 9,303
  • 17
  • 30