I want to get a calculation result from a user-inputted string, while using math
functions such as sin
or ceil
. I also would like to be able to do it as sin(30)
, not math.sin(30)
. I thought doing
from math import *
would work, because when I import all, it shows as a built-in function, and built-in functions are imported. However, when I ran the code, it showed that the math functions didn't work inside eval()
>>> from math import *
>>> sin
<built-in function sin>
>>> print
<built-in function print>
>>> eval("sin(30)", {}, {})
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
eval("sin(30)", {}, {})
File "<string>", line 1, in <module>
NameError: name 'sin' is not defined
Would I have to add in all of the math functions manually, or is there an easier way to do this?
Regarding "safely", it depends on what you mean. You can provide access to your global environment easily enough, giving the expression access to whatever you've imported. But there is nothing to stop a user from entering an expression that can do unintended things, so if the expression is coming from an untrusted user, then you should avoid the use of eval
.
That having been said, you can make your example work as follows:
>>> from math import *
>>> eval("sin(30)", globals())
-0.9880316240928618
>>>
Note that in this example, 30
is being interpreted as radians rather than degrees.