Python dynamic functions from strings -
i came across few related answers not want.
here code have now:
code_str = """ print "this global x = " + x print "and line done" """ x = 'mystery' func_template = lambda p: none func_template.__code__ = compile(code_str, '<string>', 'exec') func_template() # executes fine , has access x, need. # func_template('param') # raises: typeerror: <module>() takes no arguments (1 given) some background; code_str coming database, , need store lots of functions in dict can call 1 name, below:
all_funcs = {} # assuming db_result returns list of name, code tuples databse name, code in db_result: all_funcs[name] = my_compile(code) i want call needed function arguments want if know name:
result = all_funcs[by_name](arg1, arg2) edit: database trusted, not need santize or worry malicious code.
if replace __code__ object of lambda, redefine function. new argcount determined __code__.co_argcount, doesnt't matter or how many arguments lambda took before.
if want pass parameter compiled code, try eval code object directly, passing parameter in locals dictionaray:
code_str = """ print "this global x = " + x print "and line done" print param """ compiled = compile(code_str, "<string>", "exec") func_template = lambda p=none: eval(compiled, globals(), {'param': p}) x = "1" func_template() func_template("2") this way can pass keyword arguments, it's not possible use positional arguments. use
func_template = lambda **kwargs: eval(compiled, globals(), **kwargs) to pass keyword arguments given function directly.
if need return value function, you'd need compile code in 'eval' mode instead, means have limit code expressions , can't have statements.
Comments
Post a Comment