Оценка математического выражения в строке - PullRequest
94 голосов
/ 03 марта 2010
stringExp = "2^4"
intVal = int(stringExp)      # Expected value: 16

Возвращает следующую ошибку:

Traceback (most recent call last):  
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int()
with base 10: '2^4'

Я знаю, что eval может обойти эту проблему, но нет ли лучшего и, что более важно, более безопасного метода для оценки математического выражения, хранящегося в строке?

Ответы [ 11 ]

0 голосов
/ 03 марта 2010

Используйте eval в чистом пространстве имен:

>>> ns = {'__builtins__': None}
>>> eval('2 ** 4', ns)
16

Чистое пространство имен должно предотвращать инъекцию.Например:

>>> eval('__builtins__.__import__("os").system("echo got through")', ns)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute '__import__'

В противном случае вы получите:

>>> eval('__builtins__.__import__("os").system("echo got through")')
got through
0

Возможно, вы захотите предоставить доступ к математическому модулю:

>>> import math
>>> ns = vars(math).copy()
>>> ns['__builtins__'] = None
>>> eval('cos(pi/3)', ns)
0.50000000000000011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...