2011-12-23 4 views
1

Я пытаюсь построить класс python, который анализирует строку, и если она соответствует регулярному выражению, которое выглядит , как попытка вызова функции вызвать эту функцию на класса, передавая любые параметры.Как передать (несколько) параметры функции parseed regex на функцию python

Например, строка, как «Foo (» а», 20„)“перевело бы к чему-то вроде self.foo („а“, 20).

Вот код, который я до сих пор. .

class FooTranslate(object): 
    def create_string(self, letter, size): 
     return letter*size 

    def run_function(self, func_str): 
     match = re.match("([\w_]+)\((|[\W\d\w\,]+)\)", func_str) 
     if match == None: 
      print "Couldn't match a regex!" 
      return False 
     else: 
      func, fargs = match.groups() 

     try: 
      if fargs == "": 
       return self.__getattribute__(func)() 
      else: 
       return self.__getattribute__(func)(eval(fargs)) 
     except AttributeError, e: 
      print "Invalid function call: %s" % (func) 
      return False 

Этот код работает в основных случаях ...

In [1018]: foot = FooTranslate() 
In [1019]: foot.run_function("foo()") 
Foo! 
In [1020]: foot.run_function("bar(2)") 
FooFoo 

Однако в случае использования 2 аргумента функции:

In [1021]: foot.run_function("create_string('a', 2)") 

in run_function(self, func_str) 
    24     return self.__getattribute__(func)() 
    25    else: 
---> 26     return self.__getattribute__(func)(eval(fargs)) 
    27   except AttributeError, e: 
    28    print "Invalid function call: %s" % (func) 

TypeError: create_string() takes exactly 3 arguments (2 given) 

Причина, по которой вызов eval() возвращает fargs как кортеж, который create_string() принимает только как один аргумент. Любая идея, как я могу передать переменное количество аргументов через вызов функции? Или у вас есть лучший альтернативный способ сделать это?

+0

Посмотрите 'ast.literal_eval()' в качестве более безопасной альтернативы Eval. – Duncan

ответ

1

Вы можете использовать * operator, чтобы взорвать кортеж в отдельные аргументы функции. Например:

def f(a, b, c): 
    print a, b, c 

Если я называю f(...) так:

f((1,2,3)) 

Я получаю сообщение об ошибке:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: f() takes exactly 3 arguments (1 given) 

Но если я называю это так:

f(*(1,2,3)) 

Я получаю:

1 2 3 

Оператор * будет работать, если функция принимает переменное количество аргументов. Например, учитывая следующую функцию:

def f2(a, b, *args): 
    print a, b, 
    for x in args: 
     print x, 
    print 

Если я позвоню f2(*(1,2,3,4,5)) печатает:

1 2 3 4 5 
+0

Я подозреваю, что это ответ, который я ищу, спасибо! Если у кого-то есть лучшие способы сделать это (т. Е. Не использовать eval), это было бы очень полезно. – Andrew

Смежные вопросы