51
class MyClass:
    def __init__(self, i):
        self.i = i

    def get(self):
        func_name = 'function' + self.i
        self.func_name() # <-- this does NOT work.

    def function1(self):
        pass # do something

    def function2(self):
        pass # do something

This gives the error: TypeError: 'str' object is not callable

How would I go about doing this?

Note: self.func_name also does not work

5
  • 3
    Depending on your usage, you might be better off with either a list/dict of functions, or using a lambda function to pass an additional argument to the functions (the latter is mainly useful for callbacks). Commented May 20, 2013 at 3:34
  • This is not the code for which you got this error. when you do self.func_name you do not even access the local variable func_name. You are trying to access an instance variable named class name inside self - but such variable does not exist. Commented May 20, 2013 at 3:37
  • 1
    @Elazar yes my mistake. I was translating the code and missed this one. Commented May 20, 2013 at 3:57
  • 5
    There is a subtle difference between this question and question 3061. This question focuses on calling methods within a class. 3061 focuses on regular functions. Python newbies may not be a able to apply the answers that were written there to this situation. Commented Sep 17, 2015 at 3:19
  • 2
    Voted to reopen. I am said newbie and it's completely non-obvious to me how this is a duplicate of the linked question. Commented Apr 27, 2019 at 14:02

2 Answers 2

73
def get(self):
      def func_not_found(): # just in case we dont have the function
         print 'No Function '+self.i+' Found!'
      func_name = 'function' + self.i
      func = getattr(self,func_name,func_not_found) 
      func() # <-- this should work!
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for the response. Just for everyone's information, you can also give a default value to avoid exception. e.g., 'func = getattr(self, func_name, None)'. From python help (= help(getattr)): "When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case."
How can I unittest it? I tried but When I assert the function call it gives me false
6

Two things:

  1. In line 8 use,

    func_name = 'function' + str(self.i)

  2. Define a string to function mapping as,

      self.func_options = {'function1': self.function1,
                           'function2': self.function2
                           }
    
  3. So it should look as:

    class MyClass:

    def __init__(self, i):
          self.i = i
          self.func_options = {'function1': self.function1,
                               'function2': self.function2
                               }
    def get(self):
          func_name = 'function' + str(self.i)
          func = self.func_options[func_name]
          func() # <-- this does NOT work.
    
    def function1(self):
          //do something
    
    def function2(self):
          //do something
    

1 Comment

this should work as well. but the getattr solution is a very clean solution that we all can use. Thanks again Sinhayash for this novel solution. It may be useful to solve some other related issue. thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.