что делает функция eval
Функция eval() в Python
Функция eval() в Python используется для синтаксического анализа строки выражения, как выражения Python и последующего ее выполнения.
expression – обязательный строковый параметр, он анализируется и выполняется, как выражение Python.
globals – словарь, используемый для определения доступных для выполнения выражений. Стандартные встроенные методы доступны, если явно не ограничены с помощью элемента ‘__builtins__’: None.
locals – используется для указания локальных переменных и методов, доступных для функции eval().
Пример
Давайте сначала рассмотрим простой пример функции eval() в python.
eval() с пользовательским вводом
Приведенный выше пример функции eval() очень ограничен и не оправдывает ее возможности. Сила функции заключается в динамическом выполнении операторов. Мы можем выполнять произвольные объекты кода с помощью функции eval().
Давайте посмотрим на более сложный пример, где мы попросим пользователя ввести функции для выполнения.
На изображении ниже показан пример выполнения указанного выше скрипта Python.
Без функции eval мы не можем выполнять команды, введенные пользователем. В этом сила функции eval().
Риски безопасности
Вот почему, когда вы используете функцию eval() для выполнения кода ввода пользователя, вам необходимо убедиться, что введенные пользователем данные сначала проверяются, и если они в порядке, то выполняется только их. Вот тогда и пригодятся параметры globals и locals.
Глобальные и локальные переменные
Прежде чем мы решим, какие функции мы должны сделать доступными для eval(), нам нужно выяснить, какие все функции и переменные присутствуют в глобальной и локальной области. Мы можем найти эту информацию с помощью встроенных функций locals(), globals() и dir().
Давайте посмотрим на пример, где мы узнаем функции и переменные, доступные в глобальной и локальной области.
Это множество функций, к которым у eval() будет доступ. Большинство из них взяты из модуля __builtins__ и math.
Посмотрим, что произойдет, если мы укажем значение globals, как пустой словарь в функции eval.
Таким образом, для функции eval по-прежнему доступны встроенные методы. Если вы хотите ограничить доступ только к нескольким встроенным методам, вы можете указать его значение для глобальных переменных. Например, приведенный ниже код позволяет функции eval() выполнять только встроенную функцию min.
Давайте посмотрим на другой пример, где я предоставляю значение locals и отключаю доступ ко всем встроенным функциям для eval().
Давайте посмотрим на последний пример, в котором я разрешаю доступ только к некоторым методам из математического модуля. Мы также сопоставляем square_root с функцией sqrt для удобства чтения человеком.
Я ничего не указал для встроенных функций, поэтому они будут доступны для функции eval().
Ниже приведен еще один пример выполнения, показывающий, что встроенные функции доступны для выполнения.
Что делает функция eval
Метод eval() выполняет JavaScript-код, представленный строкой.
Синтаксис
Параметры
Возвращаемое значение
Описание
Н е используйте eval без необходимости!
Также eval(), как правило, медленнее альтернатив, так как вызывает интерпретатор JS, тогда как многие другие конструкции оптимизированы современными JS движками.
Есть безопасные (и быстрые!) альтернативы eval() для общих случаев использования.
Доступ к свойствам
Однако, eval() здесь не нужен. По факту, использование здесь его удивляет. Вместо него используйте доступ к свойствам, который быстрее и безопаснее:
Используйте функции вместо исполнения фрагментов кода
У JavaScript функции первого класса, что значит, что вы можете передавать функции как аргументы, хранить их в переменных или свойствах объектов и так далее. Многие DOM API созданы с учётом этого, так что вы можете (и вам следует) писать:
Замыкания также полезны как способ создания функций с параметрами без конкатенации строк.
Разбор JSON (конвертирование строк в JavaScript объекты)
Заметьте, что синтаксис JSON ограничен в сравнении с JavaScript синтаксисом, многие валидные JavaScript литералы не распарсятся в JSON. К примеру, лишние запятые в конце выражений не разрешены в JSON, а имена свойств (ключи) в объектах должны быть в двойных кавычках. Будьте уверены использовать сериализацию JSON для создания строк, которые потом будут разбираться как JSON.
Передавайте данные вместо кода
К примеру, расширение, созданное изменять содержимое веб-страниц, должно иметь правила, определённые в XPath, а не JS коде.
Выполняйте код с ограниченными правами
Если выполнять код всё-таки необходимо, желательно это делать с уменьшенными привелегиями. Этот совет подходит, главным образом, к расширениям и XUL приложениям, которые могут использовать Components.utils.evalInSandbox.
Примеры
Использование eval
Использование eval для исполнения строки, содержащей операторы JavaScript
Последнее выражение выполняется
eval() вернёт значение последнего выполняемого выражения
eval как строковое определение функции, включающее «(» и «)» как префикс и суффикс
Спецификации
Поддержка браузерами
BCD tables only load in the browser
Gecko-специфичные замечания
Смотрите также
Found a problem with this page?
Mozilla
© 2005- 2021 Mozilla and individual contributors. Content is available under these licenses.
Динамическое выполнение выражений в Python: eval()
Leo Matyushkin
Функция eval() полезна, когда необходимо выполнить динамически обновляемое выражение Python из какого-либо ввода (например, функции input() ), представленного в виде строки или объекта байт-кода. Это невероятно полезный инструмент, но то, что она может выполнять программный код, имеет важные последствия для безопасности, которые следует учесть перед ее применением.
Статья является сокращенным переводом публикации Леоданиса Посо Рамоса Python eval(): Evaluate Expressions Dynamically. Из этого руководства вы узнаете:
Разбираемся в том, как работает eval()
Вы можете использовать встроеннyю функцию eval() для динамического исполнения выражений из ввода на основе строки или скомпилированного кода. Если вы передаете в eval() строку, то функция анализирует ее, компилирует в байт-код и выполняет как выражение Python.
Сигнатура eval() определена следующим образом:
Первый аргумент: expression
При вызове eval() со строковым выражением в качестве аргумента, функция возвращает значение, полученное в результате оценки входной строки. По умолчанию eval() имеет доступ к глобальным именам, таким как x в приведенном выше примере.
Чтобы оценить строковое выражение, eval() выполняет следующую последовательность действий:
Имя аргумента expression подчеркивает, что функция работает только с выражениями, но не составными конструкциями. При попытке передачи блока кода вместо выражения будет получено исключение SyntaxError :
В eval() запрещены и операции присваивания:
SyntaxError также вызывается в случаях, когда eval() не удается распарсить выражение из-за ошибки в записи:
Таким образом, мы можем использовать compile() для предоставления объектов кода в eval() вместо обычных строк:
Использование объектов кода полезно при многократном вызове. Если мы предварительно скомпилируем входное выражение, то последующие вызовы eval() будут выполняться быстрее, так как не будут повторяться шаги синтаксического анализа и компиляции.
Второй аргумент: globals
Глобальные имена – это все те имена, которые доступны в текущей глобальной области или пространстве имен. Вы можете получить к ним доступ из любого места в вашем коде.
Все имена, переданные глобальным переменным в словаре, будут доступны eval() во время выполнения.
Вы также можете указать имена, которых нет в текущей глобальной области видимости. Чтобы это работало, нужно указать конкретное значение для каждого имени. Тогда eval() будет интерпретировать эти имена, как если бы это были глобальные переменные:
Несмотря на переданный пустой словарь ( <> ), eval() имеет доступ к встроенным функциям.
При вызове eval() без передачи пользовательского словаря в глобальные переменные аргумент по умолчанию будет использовать словарь, возвращаемый globals() в среде, где вызывается eval() :
Третий аргумент: locals
Аргумент locals также является необязательным аргументом. В этом случае словарь содержит переменные, которые eval() использует в качестве локальных имен при оценке выражения.
Локальными называются те имена (переменные, функции, классы и т.д.), которые мы определяем внутри данной функции. Локальные имена видны только изнутри включающей функции.
Выполнение выражений с eval()
Функция eval() используется, когда нужно динамически изменять выражения, а применение других техник и инструментов Python требует избыточных усилий. В этом разделе мы обсудим, как использовать eval() для булевых, математических и прочих выражений Python.
Булевы выражения
Булевы выражения – это выражения Python, которые возвращают логическое значение. Обычно они используются для проверки, является ли какое-либо условие истинным или ложным:
Зачем же может потребоваться использовать eval() вместо непосредственного применения логического выражения? Предположим, нам нужно реализовать условный оператор, но вы хотите на лету менять условие:
Теперь представьте, как бы вы реализовали то же поведение без eval() для обработки любого логического выражения.
Математические выражения
Выражения общего вида
Вы можете использовать eval() и с более сложными выражениями Python, включающими вызовы функций, создание объектов, доступ к атрибутам и т. д.
Например, можно вызвать встроенную функцию или функцию, импортированную с помощью стандартного или стороннего модуля. В следующих примерах eval() используется для запуска различных системных команд.
Таким образом, можно передавать команды через какой-либо строковый интерфейс (например, форму в браузере) и выполнять код Python.
Минимизация проблем безопасности, связанных с eval()
Если вы используете Linux и приложения имеет необходимые разрешения, то злонамеренный пользователь может ввести опасную строку, подобную следующей:
Выполнение выражения удалит все файлы в текущей директории.
Ограничение globals и locals
Ограничение __builtins__
Чтобы минимизировать риски, можно переопределить __builtins__ в globals :
Ограничение имён во входных данных
Этот код напечатает большой список классов. Некоторые из этих классов довольно мощные и могут быть чрезвычайно опасны в чужих руках. Это открывает еще одну важную дыру в безопасности, которую вы не сможете закрыть, просто ограничивая окружение eval() :
Возможное решение этой уязвимости состоит в том, чтобы ограничить использование имен во входных данных набором безопасных имен либо исключить всякое использование любых имен.
Чтобы реализовать эту технику, необходимо выполнить следующие шаги:
Взглянем на следующую функцию, в которой реализованы все эти шаги:
Следующие примеры показывают, как написанная нами функция eval_expression() работает на практике:
Если нужно полностью запретить применение имен, достаточно переписать eval_expression() следующим образом:
Ограничение входных данных до литералов
Использование eval() совместно с input()
В Python 3.x встроенная функция input() читает пользовательский ввод из командной строки, преобразует его в строку, удаляет завершающий символ новой строки и возвращает результат вызывающей стороне. Поскольку результатом input() является строка, ее можно передать в eval() и выполнить как выражение Python:
Построим обработчик математических выражений
Итак, мы узнали, как работает eval() в Python и как использовать функцию на практике. Мы также выяснили, что eval() имеет важные последствия для безопасности и что обычно считается хорошей практикой избегать использования eval() в коде. Однако в некоторых ситуациях eval() может сэкономить много времени и усилий.
Модуль math мы используем для того, чтобы определить все доступные имена. Три строковые константы применяются для вывода строк в интерфейсе программы. Напишем ключевую функцию нашей программы:
Осталось лишь написать код для взаимодействия с пользователем. В функции main() мы определяем основной цикл программы для чтения введенных данных и расчета математических выражений, введенных пользователем:
Проверим результат нашей работы:
Заключение
Итак, вы можете использовать eval() для выполнения выражений Python из строкового или кодового ввода. Эта встроенная функция полезна, когда вы пытаетесь динамически обновлять выражения Python и хотите избежать проблем с созданием собственного обработчика выражений. Однако пользоваться ей стоит с осторожностью.
Другие наши недавние статьи с подробным разбором различных аспектов стандартной библиотеки Python:
Eval: выполнение строки кода
Встроенная функция eval позволяет выполнять строку кода.
Строка кода может быть большой, содержать переводы строк, объявления функций, переменные и т.п.
Результатом eval будет результат выполнения последней инструкции.
Код в eval выполняется в текущем лексическом окружении, поэтому ему доступны внешние переменные:
Значения внешних переменных можно изменять:
Без use strict у eval не будет отдельного лексического окружения, поэтому x и f будут видны из внешнего кода.
Использование «eval»
В современной разработке на JavaScript eval используется весьма редко. Есть даже известное выражение – «eval is evil» («eval – это зло»).
Пожалуйста, имейте в виду, что код в eval способен получать доступ к внешним переменным, и это может иметь побочные эффекты.
Использование внутри eval локальных переменных из внешнего кода считается плохим решением, так как это усложняет задачу по поддержке такого кода.
Существует два пути, как гарантированно избежать подобных проблем.
Если код внутри eval не использует внешние переменные, то вызывайте его так – window.eval(. ) :
В этом случае код выполняется в глобальной области видимости:
Если коду внутри eval нужны локальные переменные, поменяйте eval на new Function и передавайте необходимые данные как аргументы:
Конструкция new Function объясняется в главе Синтаксис «new Function». Она создаёт функцию из строки в глобальной области видимости. Так что локальные переменные для неё невидимы, но всегда можно передать их как аргументы. Получается очень аккуратный код, как в примере выше.
Итого
Вызов eval(code) выполняет строку кода и возвращает результат последней инструкции.
Задачи
Eval-калькулятор
Создайте калькулятор, который запрашивает ввод какого-нибудь арифметического выражения и возвращает результат его вычисления.
В этой задаче нет необходимости проверять полученное выражение на корректность, просто вычислить и вернуть результат.
Давайте будем использовать eval для вычисления арифметических выражений:
Встроенная функция Python eval ()
Дата публикации Oct 19, 2019
Давайте разберемся со встроенной функцией eval () в python.
Это будет короткая статья о функции eval в python, в которой я объясню вам функцию eval, ее синтаксис и несколько вопросов, которые часто задают в интервью, чтобы вы четко поняли ее и с легкостью ответили на эти вопросы. Чтобы получить полный код, нажмите на мойGitHub репозиторийснизу:
Тан-N-Прабх / Python
github.com
Давайте начнем:
1. Что такое eval () в python и каков его синтаксис?
Синтаксис
Синтаксис функции eval показан ниже:
Аргументы или параметры
Возвращаемое значение
Возвращаемое значение будет результатом вычисленного выражения. Часто тип возвращаемого значения будет целым числом.
2. Где в основном используется функция eval?
Функция Eval в основном используется в ситуациях или приложениях, которые должны оценивать математические выражения. Также, если пользователь хочет вычислить строку в коде, он может использовать функцию eval, потому что функция eval оценивает строковое выражение и в результате возвращает целое число.
3. В чем разница между input () и eval ()?
Теперь вы все знаете, что input () принимает пользовательский ввод, но когда пользователь вводит целое число в качестве входных данных, функция ввода возвращает строку, но в случае eval она будет оценивать возвращаемое значение из строки в целое число. Я знаю, что большинство из вас смущены, позвольте мне прояснить ваше замешательство, приведя пример:
Смотрите, как я уже сказал, я ввел целое число10+ 10где я ожидал результата20 (10 + 10)но метод ввода вернул строку с тем же введенным значением.
4. Можем ли мы выполнить математические операции, используя функцию eval, приведите пример?
Да, мы можем выполнять математические операции, используя функцию eval, как показано ниже:
Посмотрите, как я сказал, если вы передаете входные данные в виде строки, а функция eval вычисляет выражение и возвращает результат в виде целого числа.
Это все, что вам нужно знать, чтобы начать работу с функцией eval в python, теперь вы знаете все ответы на поставленные выше вопросы. Одни и те же вопросы могут задаваться не всегда, дело в том, чтобы лучше понять концепции, тогда вы сможете ответить на любые вопросы. Если вы хотите потратить некоторое время на чтение материала о функции eval, я рекомендую вам, ребята, прочитать документацию по функции eval, показанную ниже:
docs.python.org
Спасибо, ребята, это конец статьи, как я уже сказал, это небольшая статья. Если у вас, ребята, есть какие-то сомнения или если вы застряли с чем-то, пожалуйста, дайте мне знать в комментариях ниже, я обязательно отвечу на все ваши вопросы. Ладно время прощаться, прекрасного дня.