stringExp = "2^4"
intVal = int(stringExp) # Expected value: 16
This returns the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int()
with base 10: '2^4'
I know that eval
can work around this, but isn't there a better and - more importantly - safer method to evaluate a mathematical expression that is being stored in a string?
Some safer alternatives to
eval()
andsympy.sympify().evalf()
*:*SymPy
sympify
is also unsafe according to the following warning from the documentation.This is a massively late reply, but I think useful for future reference. Rather than write your own math parser (although the pyparsing example above is great) you could use SymPy. I don't have a lot of experience with it, but it contains a much more powerful math engine than anyone is likely to write for a specific application and the basic expression evaluation is very easy:
Very cool indeed! A
from sympy import *
brings in a lot more function support, such as trig functions, special functions, etc., but I've avoided that here to show what's coming from where.Use
eval
in a clean namespace:The clean namespace should prevent injection. For instance:
Otherwise you would get:
You might want to give access to the math module:
Python already has a function for safely evaluating strings containing literal expressions:
http://docs.python.org/2/library/ast.html#ast.literal_eval
If you don't want to use eval, then the only solution is to implement the appropriate grammar parser. Have a look at pyparsing.
Pyparsing can be used to parse mathematical expressions. In particular, fourFn.py shows how to parse basic arithmetic expressions. Below, I've rewrapped fourFn into a numeric parser class for easier reuse.
You can use it like this