eval¶
Returns a result of the evaluation of a Python expression.
Syntax¶
eval (expression[, globals[, locals]])
expression Required. The arguments are a Unicode or Latin-1 encoded string globals Optional. A dictionary defining the namespace in which the expression is evaluated. locals Optional. A dictionary defining the local namespace.
Return Value¶
Time Complexity¶
Remarks¶
The expression argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the globals and locals dictionaries as global and local namespace. If the globals dictionary is present and lacks ‘__builtins__’, the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard __builtin__ module and restricted environments are propagated. If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where eval() is called. The return value is the result of the evaluated expression. Syntax errors are reported as exceptions.
This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string. If the code object has been compiled with ‘exec’ as the mode argument, eval()‘s return value will be None. Hints: dynamic execution of statements is supported by the exec statement. Execution of statements from a file is supported by the execfile() function. The globals() and locals() functions returns the current global and local dictionary, respectively, which may be useful to pass around for use by eval() or execfile().
See ast.literal_eval() for a function that can safely evaluate strings with expressions containing only literals. See also exec statement and execfile() and compile() functions.
Example 1¶
>>> x = 1 >>> print eval('x+1') 2 >>> eval('2*2') 4 >>> eval("len('bamf')") 4
Example 2¶
>>> # this example shows how eval can access global namespace; this is a potential security hazard >>> eval("os.getcwd()") NameError: name 'os' is not defined >>> import os >>> eval("os.getcwd()") 'C:\\Program Files\\PyScripter'
Example 3¶
>>> # this example shows how providing globals argument prevents eval from accessing real globals dictionary >>> eval("os.getcwd()", <>) NameError: name 'os' is not defined >>> # that example however can be bypassed by using __import__ function inside eval >>> eval('__import__("os").getcwd()', <>) 'C:\\Program Files\\PyScripter'
Example 4¶
>>> # this example shows how to prevent eval from importing any modules >>> eval('__import__("os").getcwd()', '__builtins__': <>>) Traceback (most recent call last): File "", line 1, in File "", line 1, in NameError: name '__import__' is not defined
Функция 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