Python eval ()

Метод eval () анализирует выражение, переданное этому методу, и запускает выражение (код) Python в программе.

Проще говоря, eval()функция запускает код Python (который передается в качестве аргумента) внутри программы.

Синтаксис eval():

 eval (выражение, globals = None, locals = None)

Параметры eval ()

eval()Функция принимает три параметра:

  • выражение - строка анализируется и оценивается как выражение Python
  • globals (необязательно) - словарь
  • locals (необязательно) - объект отображения. Словарь - это стандартный и часто используемый тип сопоставления в Python.

Использование глобальных и локальных переменных будет обсуждаться позже в этой статье.

Возвращаемое значение из eval ()

Метод eval () возвращает результат, вычисленный на основе выражения.

Пример 1: Как eval () работает в Python

 x = 1 print(eval('x + 1'))

Вывод

 2

Здесь eval()функция оценивает выражение x + 1и printиспользуется для отображения этого значения.

Пример 2: Практический пример демонстрации использования eval ()

 # Perimeter of Square def calculatePerimeter(l): return 4*l # Area of Square def calculateArea(l): return l*l expression = input("Type a function: ") for l in range(1, 5): if (expression == 'calculatePerimeter(l)'): print("If length is ", l, ", Perimeter = ", eval(expression)) elif (expression == 'calculateArea(l)'): print("If length is ", l, ", Area = ", eval(expression)) else: print('Wrong Function') break

Вывод

 Введите функцию: calculateArea (l) Если длина равна 1, Area = 1 Если длина равна 2, Area = 4 Если длина равна 3, Area = 9 Если длина равна 4, Area = 16

Предупреждения при использовании eval ()

Рассмотрим ситуацию, когда вы используете систему Unix (macOS, Linux и т. Д.) И импортировали osмодуль. Модуль os предоставляет переносимый способ использования функций операционной системы, таких как чтение или запись в файл.

Если разрешить пользователям вводить значение с помощью eval(input()), пользователь может выдавать команды в файл изменений или даже удалить все файлы с помощью команды: os.system('rm -rf *').

Если вы используете eval(input())в своем коде, рекомендуется проверить, какие переменные и методы может использовать пользователь. Вы можете увидеть, какие переменные и методы доступны, используя метод dir ().

 from math import * print(eval('dir()'))

Вывод

('__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', ' asinh ',' atan ',' atan2 ',' atanh ',' ceil ',' comb ',' copysign ',' cos ',' ch ',' градусы ',' dist ',' e ',' erf ' , 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', ' inf ',' isclose ',' isfinite ',' isinf ',' isnan ',' isqrt ',' ldexp ',' lgamma ',' log ',' log10 ',' log1p ','log2 ',' modf ',' nan ',' os ',' perm ',' pi ',' pow ',' prod ',' радианы ',' остаток ',' sin ',' sinh ',' sqrt ' , 'tan', 'tanh', 'tau', 'trunc')

Ограничение использования доступных методов и переменных в eval ()

Чаще всего все доступные методы и переменные, используемые в выражении (первый параметр eval()), могут не понадобиться или даже могут иметь брешь в безопасности. Возможно, вам придется ограничить использование этих методов и переменных для eval(). Вы можете сделать это, передав функции дополнительные глобальные и локальные параметры (словари) eval().

1. Если опущены и глобальные, и локальные параметры.

Если оба параметра опущены (как в наших предыдущих примерах), выражение выполняется в текущей области. Вы можете проверить доступные переменные и методы, используя следующий код:

 print(eval('dir()')

2. Передача глобальных параметров; параметр locals опущен

Параметры globals и locals (словари) используются для глобальных и локальных переменных соответственно. Если словарь locals опущен, по умолчанию используется словарь globals. Это означает, что глобальные переменные будут использоваться как для глобальных, так и для локальных переменных.

Примечание. Вы можете проверить текущий глобальный и локальный словарь в Python, используя встроенные методы globals () и locals () соответственно.

Пример 3: передача пустого словаря в качестве параметра глобальных переменных

 from math import * print(eval('dir()', ())) # The code will raise an exception print(eval('sqrt(25)', ()))

Вывод

 ('__builtins__') Traceback (последний вызов последним): файл "", строка 5, в print (eval ('sqrt (25)', ())) Файл "", строка 1, в NameError: имя 'sqrt' не определено

Если вы передадите пустой словарь как глобал, только __builtins__доступны expression(первый параметр eval()).

Несмотря на то, что мы импортировали mathмодуль в вышеуказанную программу, выражение не может получить доступ к функциям, предоставляемым математическим модулем.

Пример 4: Обеспечение доступности определенных методов

 from math import * print(eval('dir()', ('sqrt': sqrt, 'pow': pow)))

Вывод

 ('__builtins__', 'pow', 'sqrt')

Здесь выражение можно использовать только sqrt()и те pow()методы , наряду с __builtins__.

Также можно изменить имя метода, доступного для выражения, по вашему желанию:

 from math import * names = ('square_root': sqrt, 'power': pow) print(eval('dir()', names)) # Using square_root in Expression print(eval('square_root(9)', names))

Вывод

 ('__builtins__', 'power', 'square_root') 3.0

В приведенной выше программе square_root()вычисляется квадратный корень с использованием sqrt(). Однако попытка использовать sqrt()напрямую вызовет ошибку.

Пример 5: Ограничение использования встроенных модулей

Вы можете ограничить использование __builtins__в выражении следующим образом:

 eval(expression, ('__builtins__': None))

3. Передача как глобальных, так и локальных словаря

Вы можете сделать необходимые функции и переменные доступными для использования, передав словарь locals. Например:

 from math import * a = 169 print(eval('sqrt(a)', ('__builtins__': None), ('a': a, 'sqrt': sqrt)))

Вывод

 13,0

В этой программе выражение может иметь только sqrt()метод и переменную a. Все остальные методы и переменные недоступны.

Ограничение использования eval()путем передачи глобальных и локальных словарей сделает ваш код безопасным, особенно когда вы используете ввод, предоставленный пользователю для eval()метода.

Примечание. Иногда eval()это небезопасно даже с ограниченными именами. Когда объект и его методы становятся доступными, можно делать практически все. Единственный безопасный способ - это проверить введенные пользователем данные.

Интересные статьи...