Подтвердить что ты не робот

Использование eval в Python?

В Python я наткнулся на функцию eval() во время игры. Я не могу придумать случай, когда нужна эта функция, за исключением, возможно, синтаксического сахара. Может ли кто-нибудь привести пример?

4b9b3361

Ответ 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.