Функция eval() в Python: как происходит динамическое выполнение выражений
Благодаря этой публикации вы узнаете, зачем в Python нужна встроенная функция eval(), и как ее максимально эффективно использовать. Помимо теории, вы ознакомитесь с примерами кода, которые демонстрируют практическое применение этой функции.
Функция eval() интерпретирует строку как код. Она используется для вычисления строк, содержащих выражения, а затем возвращает результат их выполнения. Благодаря этой функции можно динамически оценивать строчные выражения. Это делает eval() эффективным инструментом, но с ним нужно обращаться осторожно.
Давайте познакомимся с синтаксисом eval():
eval(expression, globals=None, locals=None)
В данном примере expression является строкой, в которой мы видим выражения globals и locals — это необязательные аргументы, отражающие наличие глобальной и локальной области видимости.
Во избежание путаницы стоит отметить, что для динамического выполнения кода также применять функцию exec(). Различие между ней и eval() состоит в том, что eval() способна выполнять только выражения, а функция exec() может выполнять практически любой фрагмент кода.
Теперь стоит ознакомиться с практическим использованием eval() в Python:
x = 3 code = "x + 8" result = eval(code) print(result) # Вывод: 11
Здесь функция eval() выполняет вычисление выражение x + 8, а print() отображает это значение.
А сейчас пример с интерактивным вводом данных:
user_input = input("Напишите выражение: ") # Пользователь пишет на клавиатуре "20 + 30" result = eval(user_input) print(result) # Вывод: 50
В данном примере eval() обрабатывает ввод выражения с последующим вычислением готового результата.
Функция eval() таит в себе потенциальную опасность, поскольку с ее помощью можно запускать любой строчный код. При вводе данных без необходимого уровня валидации, это может привести к проблемам в сфере кибербезопасности. К примеру, хакер может ввести произвольный опасный код, который приложение затем выполнит.
Перед вами пример неправильного использования функции:
dangerous_input = "import os; os.system('rm -rf /')" eval(dangerous_input) # Не нужно так делать!!
В этом фрагменте хакер пытается использовать eval() чтобы запустить свой код на устройстве пользователя.
Чтобы минимизировать риск при использовании функции eval(), придерживайтесь рекомендаций:
Expression — это совокупность элементов выражения. К ним относятся литералы, наименования, доступы к атрибутам, операторы или вызовы функций. Все они возвращают значение.
При работе eval() содержание expression понимается как выражение. Функция отображает результат после того, как оценит переданную при вводе строку. Перед этим eval() делает парсинг и компилирование кода, оценку выражение и возвращение результатом этой оценки.
Само по себе название expression говорит о том, что функция взаимодействует только с выражениями, а не с другими конструкциями. Вы сами можете в этом убедиться, если попытаетесь передать блок кода вместо выражения. В итоге вы увидите исключение SyntaxError.
Пример использования аргумента expression:
# Математическое строчное выражение expression = "10 * (6 + 9)" # Выполняем выражение с помощью eval result = eval(expression) print(f"Результат выражения '{expression}': {result}")
Пояснение:
expression: В данном примере мы передали строку “10 * (6 + 9)” в виде выражения. Функция eval() вычисляет результат этого математического задания. Вычисление даёт результат 150. Затем этот результат сохраняется в переменной result, и выводится на экран.
Аргумент globals ограничивает доступ к глобальным переменным, переопределяет их и создает ограниченную среду для выполнения выражений. Это может быть полезно для тестирования, вычислений или обработки выражений без влияния на рабочий код программы.
Пример работы аргумента globals:
# Определим переменные globals x = 10 y = 20 # Функция eval с передачей кастомного словаря переменных globals expr = "x + y" custom_globals = {"x": 5, "y": 15} # Выполнение с ограниченным доступом к переменным globals result = eval(expr, custom_globals) print(result) # Вывод: 20 # Попробуем вызвать eval с использованием обычных переменных globals result = eval(expr) print(result) # Вывод: 30
Пояснение:
З вышеуказанном примере мы определили переменные x = 10 и y = 20 в глобальной области видимости.
Строка expr = “x + y” содержит выражение, которое нам нужно вычислить.
В первом вызове eval() мы передаем кастомный словарь custom_globals, где значения для x и y изменены на 5 и 15. В итоге eval() рассчитывает сумму этих новых значений и показывает 20.
Во втором вызове eval() выполняется без кастомного словаря, используя оригинальные глобальные значения x = 10 и y = 20. Таким образом, использование аргумента globals позволяет контролировать, какие переменные будут доступны в выражении. Это делает выполнение кода более контролируемым.
Аргумент locals дает возможность задать локальную область видимости, которая затем используется при выполнении выражения. Это позволяет контролировать, какие локальные переменные и функции доступны внутри выражения. Аргумент locals используется вместе с globals для определения контекста, в котором будет выполняться выражение.
Пример использования аргумента locals:
# Определяем переменные globals x = 10 y = 20 # переменные locals, которые передаются в eval local_vars = {"x": 5, "y": 15, "z": 30} # Строка выражения expression = "x + y + z" # Применяем eval с передачей локальных переменных result = eval(expression, globals(), local_vars) print(f"Результат выражения '{expression}' с локальными переменными: {result}")
Пояснение:
Хотя в данном коде можно видеть глобальные переменные x = 10 и y = 20, они не будут использоваться, потому что мы передаем свои локальные переменные.
Мы создаем словарь local_vars с локальными переменными x = 5, y = 15 и z = 30. Эти переменные будут доступны только внутри вызова eval().
expression: Строка “x + y + z” будет интерпретироваться как выражение, которое использует локальные значения x, y и z из словаря local_vars.
eval(): Вызов eval() выполняется с глобальной областью видимости (через globals(), которая возвращает текущие глобальные переменные) и локальной областью видимости (через local_vars).
Результат: Значения переменных x = 5, y = 15 и z = 30 суммируются,. На выводе получаем результат 50.
Таким образом, используя аргумент locals, можно ограничить или поменять локальные переменные, которые будут применяться только внутри функции eval(). Это очень полезно, когда требуется передать временные или специфичные для конкретного вызова переменные, не затрагивая при этом глобальные.
Функцию eval() можно применять при оценке любых выражений Python, за исключением операторов. Использование eval() особенно удобно, если требуется динамически оценить выражения, когда другие методы или инструментов не подходят по причине нехватки времени. Давайте рассмотрим, как использовать eval() при оценке булевых, математических и общих выражений Python.
Булевы выражения — это выражения в языке Python, способные возвращать значения типа bool (истина или ложь). Это могут быть сравнения, логические операции и некоторые другие выражения. Обычно они используются в операторах if для проверки истинности или ложности определенного условия.
Пример использования eval() для оценки булевых выражений:
# Строчное булевое выражение expression = "6 > 4 and 1 < 3" # Оценка выражения с помощью eval result = eval(expression) print(f"Результат булевого выражения '{expression}': {result}")
Пояснение:
expression: В этом примере строка “6 > 4 and 1 < 3” содержит два логических выражения, объединенных оператором and. Первое выражение проверяет, больше ли 6, чем 4, а второе — меньше ли 1, чем 3.
Функция eval() выполняет вычисление этого выражения и возвращает результат типа bool. В данном случае, обе части выражения истинны, поэтому общий результат будет True.
Функция eval() может применяться для вычисления строчных математических выражений. Она очень удобна при вводе выражений пользователем. Давайте взглянем на пример, как при помощи eval() можно оценить математические выражения:
# Строчное математическое выражение expression = "4 + 6 * (1 - 7)" # Оценка выражения через eval result = eval(expression) print(f"Результат выражения '{expression}': {result}")
Пояснение:
expression: Строка “4 + 6 * (1 – 7)” содержит математическое выражение с операторами сложения, умножения и скобками.
Функция eval() выполняет вычисление этого выражение. Строка интерпретируется как обычное математическое выражение: сначала вычисляется выражение в скобках (1 – 7) = -6, затем умножение 6* (-6) = -36, и в конце добавляется 4 + (-36) = -32.
Вычисленный результат сохраняется в переменной result, которая выводится на экран.
Теперь, когда вы научились применять eval() с булевыми и математическими выражениями, настало время овладеть теорией использования eval() с общими выражениями Python. Это любые выражения, способные возвращают значения. Давайте посмотрим фрагмент кода, где eval() используется для оценки общих выражений.
Оценка выражений, содержащих строки и списки:
# Общее выражение, работающее со списком и строкой expression = "'Hello' + ' ' + 'World' + '!'" # Оценка выражения result = eval(expression) print(f"Результат выражения '{expression}': {result}")
Пояснение: выражение складывает строки. Получаем строку: ‘Hello World!’.
Оценка сложных выражений с логическими операциями и списками:
# Сложное выражение с использованием списка и логического выражения expression = "len([1, 2, 3]) == 3 and (5 > 3)" # Оценка выражения с помощью eval result = eval(expression) print(f"Результат выражения '{expression}': {result}")
Пояснение:
Оценка выражений с вызовами функций:
# Определяем функцию def multiply(a, b): return a * b # Общее выражение, использующее вызов функции expression = "multiply(4, 5)" # Оценка выражения с передачей функции через globals() result = eval(expression, {"multiply": multiply}) print(f"Результат выражения '{expression}': {result}")
Пояснение:
Выражение использует вызов функции multiply(4, 5), которая возвращает произведение двух чисел.
Мы передаем функцию multiply в глобальные переменные при вызове eval(), чтобы она была доступна для вычисления.
Результатом будет значение 20.
# Получаем общее выражение от пользователя user_input = input("Введите выражение: ") # Например, "10 ** 2 + 5" # Оценка выражения с помощью eval result = eval(user_input) print(f"Результат выражения '{user_input}': {result}")
Пояснение:
Пользователь может ввести любое корректное выражение Python, например: “10 ** 2 + 5” (возведение в степень и сложение). После того, как eval() выполнит выражение, получаем результат: 105.
Функция eval() может быть использована для оценки самых различных выражений в Python, от простых математических до сложных логических и строковых операций. Важно помнить, что при работе с пользовательскими вводами нужно применять меры безопасности, ограничивая доступ к встроенным функциям и глобальным переменным, чтобы избежать выполнения вредоносного кода.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…