Функция eval() в Python
Функция eval() в Python используется для синтаксического анализа строки выражения, как выражения Python и последующего ее выполнения.
eval(expression, globals=None, locals=None)
expression – обязательный строковый параметр, он анализируется и выполняется, как выражение Python.
globals – словарь, используемый для определения доступных для выполнения выражений. Стандартные встроенные методы доступны, если явно не ограничены с помощью элемента ‘__builtins__’: None.
locals – используется для указания локальных переменных и методов, доступных для функции eval().
Пример
Давайте сначала рассмотрим простой пример функции eval() в python.
x = 1 print(eval('x==1')) print(eval('x+2'))
eval() с пользовательским вводом
Приведенный выше пример функции eval() очень ограничен и не оправдывает ее возможности. Сила функции заключается в динамическом выполнении операторов. Мы можем выполнять произвольные объекты кода с помощью функции eval().
Давайте посмотрим на более сложный пример, где мы попросим пользователя ввести функции для выполнения.
# eval() with user input from math import * for l in range(1, 3): func = input("Enter Math Function to Evaluate:\n") try: print(eval(func)) except Exception as ex: print(ex) break print('Done')
На изображении ниже показан пример выполнения указанного выше скрипта Python.
Без функции eval мы не можем выполнять команды, введенные пользователем. В этом сила функции eval().
Риски безопасности
Что делать, если у нас есть импортированный модуль os и пользователь вводит команду os.system (‘rm -rf /’) для выполнения. Это приведет к удалению системных файлов и повреждению нашей среды.
Вот почему, когда вы используете функцию eval() для выполнения кода ввода пользователя, вам необходимо убедиться, что введенные пользователем данные сначала проверяются, и если они в порядке, то выполняется только их. Вот тогда и пригодятся параметры globals и locals.
Глобальные и локальные переменные
Прежде чем мы решим, какие функции мы должны сделать доступными для eval(), нам нужно выяснить, какие все функции и переменные присутствуют в глобальной и локальной области. Мы можем найти эту информацию с помощью встроенных функций locals(), globals() и dir().
Давайте посмотрим на пример, где мы узнаем функции и переменные, доступные в глобальной и локальной области.
from math import * def square_root(n): return sqrt(n) print(globals()) # dictionary representing the current global symbol table. print(locals()) # dictionary representing the current local symbol table. print(dir()) # list of names in the current local scope
, '__spec__': None, '__annotations__': <>, '__builtins__': , '__file__': '/Users/pankaj/Documents/PycharmProjects/BasicPython/basic_examples/eval_example.py', '__cached__': None, 'acos': , 'acosh': , 'asin': , 'asinh': , 'atan': , 'atan2': , 'atanh': , 'ceil': , 'copysign': , 'cos': , 'cosh': , 'degrees': , 'erf': , 'erfc': , 'exp': , 'expm1': , 'fabs': , 'factorial': , 'floor': , 'fmod': , 'frexp': , 'fsum': , 'gamma': , 'gcd': , 'hypot': , 'isclose': , 'isfinite': , 'isinf': , 'isnan': , 'ldexp': , 'lgamma': , 'log': , 'log1p': , 'log10': , 'log2': , 'modf': , 'pow': , 'radians': , 'remainder': , 'sin': , 'sinh': , 'sqrt': , 'tan': , 'tanh': , 'trunc': , 'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'square_root': > , '__spec__': None, '__annotations__': <>, '__builtins__': , '__file__': '/Users/pankaj/Documents/PycharmProjects/BasicPython/basic_examples/eval_example.py', '__cached__': None, 'acos': , 'acosh': , 'asin': , 'asinh': , 'atan': , 'atan2': , 'atanh': , 'ceil': , 'copysign': , 'cos': , 'cosh': , 'degrees': , 'erf': , 'erfc': , 'exp': , 'expm1': , 'fabs': , 'factorial': , 'floor': , 'fmod': , 'frexp': , 'fsum': , 'gamma': , 'gcd': , 'hypot': , 'isclose': , 'isfinite': , 'isinf': , 'isnan': , 'ldexp': , 'lgamma': , 'log': , 'log1p': , 'log10': , 'log2': , 'modf': , 'pow': , 'radians': , 'remainder': , 'sin': , 'sinh': , 'sqrt': , 'tan': , 'tanh': , 'trunc': , 'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'square_root': > ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'square_root', 'tan', 'tanh', 'tau', 'trunc']
Это множество функций, к которым у eval() будет доступ. Большинство из них взяты из модуля __builtins__ и math.
Посмотрим, что произойдет, если мы укажем значение globals, как пустой словарь в функции eval.
Таким образом, для функции eval по-прежнему доступны встроенные методы. Если вы хотите ограничить доступ только к нескольким встроенным методам, вы можете указать его значение для глобальных переменных. Например, приведенный ниже код позволяет функции eval() выполнять только встроенную функцию min.
Давайте посмотрим на другой пример, где я предоставляю значение locals и отключаю доступ ко всем встроенным функциям для eval().
Давайте посмотрим на последний пример, в котором я разрешаю доступ только к некоторым методам из математического модуля. Мы также сопоставляем square_root с функцией sqrt для удобства чтения человеком.
from math import * for l in range(1, 3): func = input("Enter Math Function to Evaluate.\nAllowed Functions are: square_root(x) and pow(x,y):\n") try: print(eval(func, )) except Exception as ex: print(ex) break print('Done')
Enter Math Function to Evaluate. Allowed Functions are: square_root(x) and pow(x,y): square_root(16) 4.0 Enter Math Function to Evaluate. Allowed Functions are: square_root(x) and pow(x,y): log10(100) name 'log10' is not defined Done
Я ничего не указал для встроенных функций, поэтому они будут доступны для функции eval().
Ниже приведен еще один пример выполнения, показывающий, что встроенные функции доступны для выполнения.
Enter Math Function to Evaluate. Allowed Functions are: square_root(x) and pow(x,y): min(5,4) 4 Enter Math Function to Evaluate. Allowed Functions are: square_root(x) and pow(x,y): max(10,20) 20