In Python the eval function takes two additional parameters beyond the expression
parameter, namely locals
and globals
which populate the variables the expression has access to, so a simple solution is just to pass your kwargs
to eval's locals
and everything works as expected.
import re
def calc(function, **kwargs):
if re.fullmatch(r'[0-9a-z+\-*/()]+', function) != None:
return eval(function, locals=kwargs)
return None
print(calc('x+y', x=10, y=20)) # Outputs 30
Obligatory warning on never using eval nor relying on regex as a security measure, but this works perfectly for a small concept as this.
You can read more about globals
and locals
in python here: What's the difference between globals(), locals(), and vars()?