wewa
wewa

Reputation: 1678

Call methods by string

I have the following class.

func_list= ["function1", "function2", "function3"]

class doit(object):
    def __init__(self):
        for item in func_list:
            if item == "function1":
                self.function1()
            elif item == "function2":
                self.function2()
            elif item == "function3":
                self.function3()

    def function1(self):
        #do this
        pass
    def function2(self):
        #do that
        pass
    def function3(self):
        pass

If an instance of this class is created, it iterates over a list of strings and calls methods depending on the actual string. The strings in the list have the names of the corresponding methods.

How can I do this in a more elegant way? I don't want to add another elif-path for every "function" I add to the list.

Upvotes: 6

Views: 5546

Answers (5)

Arijit Dasgupta
Arijit Dasgupta

Reputation: 51

Why don't you use lambdas?

Such as say,

def func1(a):
    return a ** 2

def func2(a, b):
    return a ** 3 + b

dic = {'Hello':lambda x: func1(x), 'World':lambda x,y: func2(x, y)} #Map functions to lambdas
print dic['Hello'](3)
print dic['World'](2,3)

Output, 9 11

OR, you can do this...

class funs():
    def func1(self, a):
        return a ** 2

    def func2(self, a, b):
        return a ** 3 + b

f = funs()
dic = {'Hello': lambda x: f.func1(x), 'World': lambda x,y: f.func2(x,y)}
print dic['Hello'](3)
print dic['World'](5,4)

Will give you, 9 129

Upvotes: 1

applicative_functor
applicative_functor

Reputation: 4976

func_list= ["function1", "function2", "function3"]

class doit(object):
    def __init__(self):
        for item in func_list:
            getattr(self, item)()
    def function1(self):
        print "f1"
    def function2(self):
        print "f2"
    def function3(self):
        print "f3"



>>> doit()
f1
f2
f3

For also private functions:

for item in func_list:
     if item.startswith('__'):
         getattr(self, '_' + self.__class__.__name__+ item)()
     else:
         getattr(self, item)()

.

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

http://docs.python.org/library/functions.html#getattr

Upvotes: 13

Bhagirath Bhardwaj
Bhagirath Bhardwaj

Reputation: 56

You can use eval which make's your program more simple and short.

list= ["function1", "function2", "function3"]

class doit(object):
    def __init__(self):
        for item in list:
            eval(item)()
    def function1(self):
        print "f1"
    def function2(self):
        print "f2"
    def function3(self):
            print "f3"

Upvotes: -2

msw
msw

Reputation: 43487

This is usually solved with a dictionary lookup because functions are first-class datatypes in Python. For example:

# map string names to callable functions
dispatch = {'func1': func1, 'func2': func2, ...}

want_to_call = 'func1'
dispatch[want_to_call](args)

Upvotes: 2

Kevin
Kevin

Reputation: 76194

class doit(object):
    def __init__(self, func_list):
        for func in func_list:
            func(self)
    #insert other function definitions here

func_list = [doit.function1, doit.function2, doit.function3]
foo = doit(func_list)

Upvotes: 0

Related Questions