python - Alternative to exec -


i'm trying code python (3.4.4) gui tkinter should allow fit arbitrary function datapoints. start easy, i'd create input-function , evaluate it. later, plot , fit using curve_fit scipy.

in order so, create dynamic (fitting) function user-input-string. found , read exec, people (1) not safe use , (2) there better alternative (e.g. here , in many other places). so, wondering alternative in case?

here example code 2 nested functions works it's not dynamic:

def buttonfit_press():     def f(x):          return x+1     return f   print(buttonfit_press()(4)) 

and here code gives rise nameerror: name 'f' not defined before can start use xval:

def buttonfit_press2(xval):     actfitfunc = "f(x)=x+1"     execstr = "def {}:\n    return {}\n".format(actfitfunc.split("=")[0], actfitfunc.split("=")[1])     exec(execstr)     return f  print(buttonfit_press2(4)) 

an alternative approach types.functiontype discussed here (10303248) wasn't successful either...

so, question is: there alternative use scenario? or if not, how can make code exec run?

i hope it's understandable , not vague. in advance ideas , input.


@gábor erdős:

either don't understand or disagree. if code same segment in mainloop, recognizes f , can execute code segment execstr:

actfitfunc = "f(x)=x+1" execstr = "def {}:\n    return {}\n".format(actfitfunc.split("=")[0], actfitfunc.split("=")[1]) exec(execstr) print(f(4)) >>> 5 

@Łukasz rogalski:

printing execstr seems fine me:

def f(x):     return x+1 

indentation error unlikely due editor, double-checked - it's fine. introducing my_locals, calling in exec , printing in afterwards shows:

{'f': <function f @ 0x000000000348d8c8>} 

however, still nameerror: name 'f' not defined.


@user3691475:

your example similar first example. not "dynamic" in understanding, i.e. 1 can not change output of function while code running.


@dunes:

i think going in right direction, thanks. however, don't understand yet how can evaluate , use function in next step? mean is: in order able fit it, have extract fitting variables (i.e. a in f(x)=a*x+b) or evaluate function @ various x-values (i.e. print(f(3.14))).

the problem exec/eval, can execute arbitrary code. use exec or eval need either parse code fragment ensure doesn't contain malicious code (an incredibly hard task), or sure source of code can trusted. if you're making small program personal use that's fine. big program that's responsible sensitive data or money, not. seem use case counts having trusted source.

if want create arbitrary function @ runtime, use combination of lambda expression , eval. eg.

func_str = "lambda x: x + 1" # equates f(x)=x+1 func = eval(func_str) assert func(4) == 5  

the reason why attempt isn't working locals(), in context of function, creates copy of local namespace. mutations resulting dictionary not effect current local namespace. need like:

def g():     src = """ def f(x):     return x + 1     """     exec_namespace = {} # exec place function f in dictionary     exec(src, exec_namespace)     return exec_namespace['f'] # retrieve f 

Comments