English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Основной курс Python

Управление потоком Python

Функции в Python

Типы данных в Python

Операции с файлами Python

Объекты и классы Python

Даты и время Python

Продвинутые знания Python

Руководство Python

Метод использования eval() Python и примеры

Внутренние функции Python

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

Короче говоря, метод eval() выполняет python-код (как параметр передается) в программе.

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

eval(expression, globals=None, locals=None)

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

У eval() есть три параметра:

  • expression-Анализ и оценка как строки Python-выражения

  • globals(по желанию)- словарь

  • locals(по желанию)- объект карты. Словарь является одним из стандартных типов карт в Python.

Обсудим позже в этой статьеГлобальные переменные (globals)иЛокальныеПеременные (locals)использование.

Значение eval() возвращает

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

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

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

При запуске этого приложения, вывод будет:

2

Здесь eval() вычисляет выражение x + 1 и выводит его.

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

# периметр квадрата
def calculatePerimeter(l):
  return 4 * l
# квадрат面积的平方
def calculateArea(l):
  return l * 1
property = input("Введите функцию, которую нужно использовать: ")
for l in range(1, 5):
    if (property == 'calculatePerimeter(l)'):
        print("Если длина равна", l, ", периметр =", eval(property))
    elif (property == 'calculateArea(l)'):
        print("Если длина равна", l, ", площадь =", eval(property))
    else:
      print('Ошибка функции')
      break

Вывод программы будет следующим:

Введите функцию, которую нужно использовать: calculatePerimeter(l)
Если длина равна 1, периметр = 4
Если длина равна 2, периметр = 8
Если длина равна 3, периметр = 12
Если длина равна 4, периметр = 16

Почему нужно быть осторожным при использовании eval()?

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

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

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

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

Когда вы запустите этот程序, вывод будет подобен:

['__annotations__', '__builtins__', '__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', 'sin', 'sinh', 'sqrt', 'squareRoot', 'tan', 'tanh', 'tau', 'trunc']

限制在eval()中使用可用的方法和变量

通常,可能不需要使用Выражение(eval()的第一个参数)中使用的所有可用方法和变量,甚至可能有安全漏洞。您可能需要限制将这些方法和变量用于eval()。您可以通过将可选的globalsиlocals参数(字典)传递给eval()方法来实现。

1.当省略globals和locals参数时

如果两个参数都被省略(如前面的示例所示),则在当前范围内执行该Выражение。您可以使用以下代码检查可用的变量和方法:

print(eval('dir()'))

2.传递全局参数;省略locals参数

globals和locals参数(字典),分别用于全局和局部变量。如果省略了locals字典,则默认为globals字典。这意味着,globals将用于全局变量和局部变量。

注意:您可以分别使用globals()иlocals()内置方法在Python中检查当前的全局字典和局部字典。

将空字典作为全局参数传递

from math import *
print(eval('dir()', {}))
# 下面的代码将引发异常
# print(eval('sqrt(25)', {}))

如果将空字典作为globals传递,则仅__builtins__可用于表达式(expression)(eval()的第一个参数)。即使我们在上面的程序中导入了math模块,表达式(expression)也无法访问math模块提供的任何功能。

При запуске этого приложения, вывод будет:

__builtins__

使某些方法可用

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

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

Кроме того, вы можете изменить функции и переменные, доступные дляВыражениеимя метода (expression)

from math import *
print(eval('dir()', {'squareRoot': sqrt, 'pow': pow}))
# Использование квадратного корня в выражении
print(eval('squareRoot(9)', {'squareRoot': sqrt, 'pow': pow}))

В aforementioned программе, функция squareRoot() вычисляет квадратный корень (аналогичные функции, такие как sqrt()). Но попытка использования sqrt() вызовет ошибку.

Ограничение использования __builtins__

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

использование: eval(expression, {'__builtins__': None})

3. Через глобальные и локальные словари

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

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

При запуске этого приложения, вывод будет:

 2.23606797749979

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

передаваяglobalsиlocalsИспользование словаря для ограничения использования eval() сделает ваш код безопасным, особенно когда вы используете ввод用户提供аемый методу eval().

Внутренние функции Python