В Python я наткнулся на функцию eval()
во время игры. Я не могу придумать случай, когда нужна эта функция, за исключением, возможно, синтаксического сахара. Может ли кто-нибудь привести пример?
Использование eval в Python?
Ответ 1
eval
и exec
удобны быстро и грязно, чтобы получить некоторый исходный код динамически, возможно, немного его немного, а затем выполнить - но они вряд ли когда-либо будут лучшим способом, особенно в производстве кода, в отличие от прототипов "быстрых и грязных" и т.д.
Например, если мне приходилось иметь дело с такими динамическими источниками Python, я бы дошел до модуля ast - ast.literal_eval
БОЛЬШЕ безопаснее, чем eval
(вы можете вызвать его непосредственно в строковой форме выражения, если это одноразовый и полагаться только на простые константы или сначала node = ast.parse(source)
, а затем сохранить node
вокруг, возможно, нарисуйте его подходящими посетителями, например, для поиска переменных, затем literal_eval
node) - или, поместив node в правильную форму и проверив его для проблем безопасности, я мог бы compile
его (давая объект кода) и построить из него новый объект функции. Гораздо менее простой (за исключением того, что ast.literal_eval
так же просто, как eval
для простейших случаев!), Но безопаснее и предпочтительнее в коде качества продукции.
Для многих задач я видел, как люди (ab-) используют exec
и eval
для мощных встроенных модулей Python, таких как getattr
и setattr
, индексирование в globals()
, & c, обеспечивают предпочтительные и на самом деле часто более простые решения. Для конкретных целей, таких как синтаксический анализ JSON, библиотечные модули, такие как json
, лучше (например, см. Комментарий SilentGhost по тиннитусному ответу на этот самый вопрос). Etc и т.д.
Ответ 2
Статья в Википедии на eval
довольно информативна и описывает различные виды использования.
Некоторые из его применений:
- Оценка математических выражений
- Самонастройка компилятора
- Scripting (динамические языки в целом очень подходят для этого)
- Языковые курсы
Ответ 3
Вы можете использовать его, чтобы позволить пользователям вводить свои собственные скриптлеты: small (или даже небольшие функции), которые можно использовать для настройки поведения комплекса. В этом контексте, и если вам не нужно уделять слишком много внимания последствиям безопасности (например, у вас есть образованная база пользователей), тогда eval() может быть хорошим выбором.
Ответ 4
В прошлом я использовал eval() для добавления интерфейса отладки в мое приложение. Я создал службу telnet, которая бросила вас в среду запущенного приложения. Входы выполнялись через eval(), чтобы вы могли интерактивно запускать команды Python в приложении.
Ответ 5
В программе, которую я когда-то писал, у вас был входной файл, в котором вы могли указывать геометрические параметры как значения, так и выражения python предыдущих значений, например:
a=10.0
b=5.0
c=math.log10(a/b)
Анализатор python считывает этот входной файл и получает окончательные данные, оценивая значения и выражения, используя eval().
Я не утверждаю, что это хорошее программирование, но мне не нужно было вести ядерный реактор.
Ответ 6
eval()
обычно не очень полезен. Одна из немногих вещей, которые я использовал для этого (ну, на самом деле это был exec()
, но он довольно похож) позволял пользователю script приложение, которое я написал в Python. Если бы он был написан как нечто вроде С++, мне пришлось бы внедрить интерпретатор Python в приложение.
Ответ 7
Eval - это способ взаимодействия с интерпретатором Python изнутри программы. Вы можете передавать литералы в eval и оценивать их как выражения python.
Например -
print eval("__import__('os').getcwd()")
вернет текущий рабочий каталог.
веселит
Ответ 8
Я использую его как быстрый парсер JSON...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
Ответ 9
Я использовал его для ввода значений переменных в основную программу:
test.py var1 = 2 var2 = True
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
Грубый способ разрешить ключевые слова args в основной программе. Если есть лучший способ, дайте мне знать!
Ответ 10
eval() для одного предложения, а exec() - для нескольких.
Обычно мы используем их для добавления или посещения некоторых скриптов, как и для оболочки bash.
из-за того, что они могут запускать некоторые байтовые скрипты в памяти, если у вас есть важные данные или script, вы можете декодировать и разархивировать свой "секрет", а затем делать все, что хотите.
Ответ 11
Я просто наткнулся на хорошее использование eval. Я писал набор тестов для некоторого кода и создал класс Test, где каждый метод был тестом, который должен быть запущен. Я хотел, чтобы я мог запускать все методы тестирования без необходимости индивидуального вызова каждого метода. Итак, я написал что-то довольно грязное.
class Test:
def __init__(self, *args):
#bs
def test1(self):
#bs
def test2(self):
#bs
if __name__ == "__main__":
import argparse
#argparse bs
test = Test(*bs_args)
for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
print(eval('test.{func}()'.format(func = func)))
Динамическая оценка произвольных тестовых случаев довольно крутая. Мне просто нужно написать этот метод, и после сохранения я могу включить этот метод в свой тестовый набор. Что касается кода, я в основном просто проверяю методы, определенные в тестовом объекте, и удостоверяюсь, что они не являются "волшебными" методами или атрибутами python для объекта Test. После этого я могу предположить, что они являются методами и могут быть оценены.
Ответ 12
Вы можете использовать eval в декораторе:
#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
print("The number is %i", i)
#call
printNumber()
в то время как вы не можете использовать сложные выражения, например
@lambda fun: lambda: fun(10)
def ...
ни
@(lambda fun: lambda: fun(10))
def ...
Вы не можете использовать там лямбда-выражение, потому что декоратор должен быть либо идентификатором:
@myModule.functionWithOneArg
или вызов функции:
@functionReturningFunctionWithOneArg(any, "args")
Вы видите, что вызов функции eval со строкой имеет здесь действительный синтаксис, но выражение лямбда нет. (- > https://docs.python.org/3/reference/compound_stmts.html#function-definitions)
Ответ 13
Я использую exec
для создания системы плагинов в Python.
try: exec ("from " + plugin_name + " import Plugin") myplugin = Plugin(module_options, config=config) except ImportError, message: fatal ("No such module " + plugin_name + \ " (or no Plugin constructor) in my Python path: " + str(message)) except Exception: fatal ("Module " + plugin_name + " cannot be loaded: " + \ str(sys.exc_type) + ": " + str(sys.exc_value) + \ ".\n May be a missing or erroneous option?")
С плагином вроде:
class Plugin: def __init__ (self): pass def query(self, arg): ...
Вы сможете называть его так:
result = myplugin.query("something")
Я не думаю, что у вас могут быть плагины в Python без exec
/eval
.