-1

In the following code how to make the unicode data callable.The error that i get is //TypeError: 'unicode' object is not callable

 def test(test_config):
    for i in test_config:
      print i.header //prints func1
      print type(i.header) // prints unicode
      try:
        #i.header()//TypeError: 'unicode' object is not callable
        func = globals()[i.header]
        print func  # found it
        func()
      except AttributeError:
        logging.error("Method  %s not implemented"%(i.header)) 

  def func1():
      print "In func1"

 test(u'func1')      
Rajeev
  • 44,985
  • 76
  • 186
  • 285

3 Answers3

4

If I understand, what you're trying to do is find the function whose name is referenced by the i.header variable, and then call it. (The title is confusing, it makes the impression you want to make the actual unicode instance callable).

This can be done using the globals():

func = globals()[i.header]
print func  # found it
func()  # call it
shx2
  • 61,779
  • 13
  • 130
  • 153
  • 1
    If the idea is that `i.header` contains the name of a function, something like this is the best way to get it to work. But it's not the best idea - passing around function names as data is not totally safe. It would be better if you could find a different design, such as passing around the function objects directly. – Peter DeGlopper Nov 22 '13 at 06:39
  • func = globals()[i.header] KeyError: u'func1' – Rajeev Nov 22 '13 at 06:41
  • this means the name `func1` is not defined at the point you're trying to access it. Can you please post a complete example which show how to get this error? – shx2 Nov 22 '13 at 06:42
  • No i have defined func1..Please see the updated question – Rajeev Nov 22 '13 at 06:43
  • I'm sorry, you code is still incomplete. Please post your full example, including the call to `test` and the error message, including traceback – shx2 Nov 22 '13 at 06:50
  • Please see the updated question again – Rajeev Nov 22 '13 at 06:52
3

Create a dict of functions that you want to call using a string:

def test(test_config):
    for i in test_config:
      print i.header //prints func1
      print type(i.header)
      try:
        methods[i.header]()
      except (AttributeError, TypeError):
        logging.error("Method  %s not implemented"%(i.header)) 

def func1():
    print "In func1"
def func2():
    print "In func2"

methods = {u'func1':func1, u'func2':func2} #Methods that you want to call

Using class:

class A:
    def test(self, test_config):
        try:
          getattr(self, i.header)()
        except AttributeError:
           logging.error("Method  %s not implemented"%(i.header)) 

    def func1(self):
        print "In func1"
x = A()
x.test(pass_something_here)
Serhiy
  • 4,357
  • 5
  • 37
  • 53
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
3

Here is a nice way using a decorator

header_handlers = {}

def header_handler(f):
    header_handlers[f.__name__] = f
    return f

def main():
    header_name = "func1"
    header_handlers[header_name]()

@header_handler
def func1():
    print "func1"

@header_handler
def func2():
    print "func2"

@header_handler
def func3():
    print "func3"

if __name__ == "__main__":
    main()

This way it's obvious whether a function is a header handler or not

John La Rooy
  • 295,403
  • 53
  • 369
  • 502