Python – Call a function of an object which is stored in a dict

Question:

I have an Class which creates objects that contain a dict of functions. These functions are defined in the class.

class Foo:

    def __init__(self, name, functions):
        self.name = name
        self.functions = functions

    def myFunction1(self):
        print self.name
        return 'foo'

    def myFunction2(self):
        return 'bar'

In another file, I instance an object of the previous class and I want to run one of the functions that is in the dict.

from foo import Foo

myFunctions = Foo.('a name', {0 : Foo.myFunction1, 1 : Foo.myFunction2})

myFunctions.functions[0]()

I have this error :
TypeError: unbound method myFunction1() must be called with Foo instance as first argument.

I understand that when I execute the last line, I just call the function without call it with an object of Foo as first argument. But I can not write this :

myFunctions.myFunctions.functions[0]()

How can I call a function of this class which is stored in a dict attribute ?

Asked By: alexis.

||

Answers:

You can call functions as a dictionary like this:

tmp = Foo()
tmp.functions={0:tmp.myFunction1, 1:tmp.myFunction2}
myFunctions = tmp.functions
print myFunctions.functions[0]()
Answered By: Valijon

If you need an object method, best way is to write another function that will call the correct function

class Foo:

    def __init__(self, functions):
        self.functions = functions

    def myFunction1(self):
        return 'foo'

    def myFunction2(self):
        return 'bar'

    def run_func(self, func_key, *args, **kwargs):
        func_name = self.functions.get(func_key)
        if func_name and hasattr(self, func_name):
            return getattr(self, func_name)(*args, **kwargs)
        else:
            return None

fun_dict = {0:'myFunction1', 1:'myFunction2'}
a = Foo(fun_dict)
print a.run_func(0)

You can send even arguments in this way.

def myFunction1(self, name):
    return name

print a.run_func(0, "test")

This will print test by the myFunction1

Answered By: thiruvenkadam

I do not really understand what you are trying to achieve with this functions dictionary, but note that instance.function() is equivalent to Class.function(instance). In the former, instance is implicitly passed as the self parameter; in the latter, you pass it explicitly.

Thus, you could try the following.

foo = Foo({0 : Foo.myFunction1, 1 : Foo.myFunction2})
print foo.functions[0](foo)
Answered By: tobias_k

Here is the simplest way to switch between functions:

       dict = {0 : Foo.myFunction1(), 1 : Foo.myFunction2()}
       function = fn_dict.get(0)
       function()
Answered By: Karam Qusai

For the next reader, I’d suggest you to read https://stackoverflow.com/a/32284348/13213188

Helps working with class functions stored in dicts, no need to create any instance

Answered By: Marc Giannuzzi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.