6

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.

2
  • 3
    as a note, don't call your variable list, as it is the name of a python built-in function. Something like funclist or flist would be fine ;) Commented Jul 25, 2012 at 12:51
  • You should put function objects in the list, rather than strs, and just call each one. Commented Jul 25, 2012 at 13:31

5 Answers 5

13
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

Sign up to request clarification or add additional context in comments.

6 Comments

I think this answer would be slightly better if you mentioned that the magic was done in the getattr function and provided a link to the documentation.
It would also be good to get rid of the list variable, since it is not used.
@black_dragon: Great, this is what I wanted to do. But how do I access private-methods like def __function4(self): print "private"?
The private function __function4 would be accessed as _doit__function4, as that is how the name gets mangled to make it appear to be private.
@wewa You should avoid __names. See stackoverflow.com/questions/165883/… for details. Just use _names.
|
2

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) 

Comments

1

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

Comments

0
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) 

Comments

-2

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" 

2 Comments

To use exec would be another possibility.
-1, eval and exec are things that should never appear in Python code. They're security vulnerabilities and completely overkill here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.