2011-12-23 61 views
1

我試圖構建一個解析字符串的python類,如果它匹配的正則表達式看起來像一個函數調用嘗試調用該函數的正則表達式 類,傳入任何參數。如何將(多個)正則表達式解析函數參數傳遞給一個python函數

例如像 「富(」 A」,20 「)的字符串」 會轉化成類似self.foo( 「A」,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

相關問題