Как вызвать метод, имя которого хранится в переменной

В следующем коде, как сделать данные Unicode доступными для вызова. Ошибка, которую я получаю, это //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')      

person Rajeev    schedule 22.11.2013    source источник
comment
вы пытаетесь вызвать метод, на name которого ссылается переменная i.header?   -  person shx2    schedule 22.11.2013
comment
Пожалуйста, смотрите обновленный вопрос   -  person Rajeev    schedule 22.11.2013
comment
Что вы ожидаете от него, когда вы его вызываете?   -  person Sweeney Todd    schedule 22.11.2013
comment
Вы ожидаете, что "print" ('Hello World.') сработает? Если да, то в питоне так не работает.   -  person Hyperboreus    schedule 22.11.2013


Ответы (3)


Создайте список функций, которые вы хотите вызывать, используя строку:

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

Использование класса:

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)
person Ashwini Chaudhary    schedule 22.11.2013
comment
Есть ли другой способ без использования словаря? - person Rajeev; 22.11.2013
comment
+1 Явный dict следует предпочесть поиску globals(). Вы же не хотите, чтобы кто-то случайно нашел заголовок с именем test. - person John La Rooy; 22.11.2013
comment
@Rajeev Тогда используйте класс, и тогда вы сможете вызывать методы, используя getattr. - person Ashwini Chaudhary; 22.11.2013
comment
Не могли бы вы показать мне фрагмент - person Rajeev; 22.11.2013
comment
@Rajeev, я добавил пример. - person Ashwini Chaudhary; 22.11.2013
comment
В примере класса я всегда получаю ошибку метода, не реализованную почему? getattr(self, i.header)() ОШИБКА: root: метод func1 не реализован - person Rajeev; 22.11.2013
comment
@Rajeev Не забудьте преобразовать строку юникода в строку байтов. - person Ashwini Chaudhary; 22.11.2013

Насколько я понимаю, вы пытаетесь найти функцию, на имя которой ссылается переменная i.header, а затем вызвать ее. (Название сбивает с толку, создается впечатление, что вы хотите сделать реальный экземпляр unicode вызываемым).

Это можно сделать с помощью globals():

func = globals()[i.header]
print func  # found it
func()  # call it
person shx2    schedule 22.11.2013
comment
Если идея состоит в том, что i.header содержит имя функции, что-то вроде этого — лучший способ заставить ее работать. Но это не лучшая идея - передавать имена функций как данные не совсем безопасно. Было бы лучше, если бы вы могли найти другой дизайн, например, напрямую передавать объекты функций. - person Peter DeGlopper; 22.11.2013
comment
func = globals()[i.header] KeyError: u'func1' - person Rajeev; 22.11.2013
comment
это означает, что имя func1 не определено в тот момент, когда вы пытаетесь получить к нему доступ. Не могли бы вы опубликовать полный пример, показывающий, как получить эту ошибку? - person shx2; 22.11.2013
comment
Нет, я определил func1. См. обновленный вопрос. - person Rajeev; 22.11.2013
comment
Извините, ваш код все еще неполный. Пожалуйста, опубликуйте свой полный пример, включая вызов test и сообщение об ошибке, включая трассировку. - person shx2; 22.11.2013
comment
Пожалуйста, просмотрите обновленный вопрос еще раз - person Rajeev; 22.11.2013

Вот хороший способ использования декоратора

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

Таким образом, очевидно, является ли функция обработчиком заголовка или нет.

person John La Rooy    schedule 22.11.2013