I’m trying to build a python class that parses a string and if it matches a regex that looks
like a function call attempt to call that function on the class, passing in any parameters.
For example a string like “foo(“a”, 20″)” would translate to something like self.foo(“a”, 20).
Here is the code that I have so far..
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
This code works in the basic cases…
In [1018]: foot = FooTranslate()
In [1019]: foot.run_function("foo()")
Foo!
In [1020]: foot.run_function("bar(2)")
FooFoo
However in the case of using 2 argument functions:
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)
The reason why is that the eval() call returns fargs as a tuple, which create_string()
takes as only a single argument. Any idea how I can pass a variable number of arguments
through to a function call? Or have a better alternative way to do this?
You can use the
*operator to explode a tuple into separate arguments to a function. For example:If I call
f(...)like this:I get an error:
But if I call it like this:
I get:
The
*operator will even work if the function takes a variable number of arguments. For example, given the following function:If I call
f2(*(1,2,3,4,5))it prints: