Выполнение в python 3.9 динамического кода заданного в виде строки для проверки логического выражения

Как реализовать выполнение динамического кода заданного в виде строки для проверки логического выражения?

  1. Функции могут возвращать численное или численные значения или строку
  2. Если функция возвращает несколько значений, то должна быть возможноть в выражение обратиться к конкретному значению для дальнейших операций сравнений

Ниже приведенный псевдо код для озвученных требований Требуется код взамен EvaluateExpression для ответа на поставленный вопрос

import ast


def func1(a):
    return 5

def func2(b, c):
    return {"x":-3, "y":5, "z":9}

def func3():
    return 17

def func4(d):
    return True

def func5():
    return "Something"

#Список обрабатываемых функций
functions = [func1, func2, func3, func4, func5]

#Параметры функций
params = {
    'func1': {'a': '1'},
    'func2': {'b': '1', 'c': '3'},
    'func3': {},
    'func4': {'d': '5'},
    'func5': {},
}

#Выражение
expression = '((func1 > 1 and abs(func2.x) > func3) or ((1 < func3 <= 20) and func4) or func5 in ("Nothing","Sonething") or (func1 + func2.z) > 2*func3)'

result = EvaluateExpression(expression)

print(result)

Ответы (1 шт):

Автор решения: Yuriy Tigiev

Ниже приведенный код решает поставленную задачу с помощью compile и eval
Для решения задачи использовал материал из https://realpython.com/python-eval-function/#:~:text=You%20can%20use%20the%20built,it%20as%20a%20Python%20expression.

def func1(a):
    return 5

def func2(b, c):
    return {"x":-3, "y":5, "z":9}

def func3():
    return 17

def func4(d):
    return True

def func5():
    return "Something"


#Список обрабатываемых функций
functions = [func1, func2, func3, func4, func5]

#Параметры функций
params = {
    'func1': {'a': '1'},
    'func2': {'b': '1', 'c': '3'},
    'func3': {},
    'func4': {'d': '5'},
    'func5': {},
}

eval_parameters = {}
for f in functions:
    fr = f(**params[f.__name__])
    if isinstance(fr,dict):
        for k, v in fr.items(): 
            eval_parameters[f.__name__ + "_" + k] = v
    else:
        eval_parameters[f.__name__] = fr

print(eval_parameters)        
        
#Выражение
expression = '((func1 > 1 and abs(func2_x) > func3) or ((1 < func3 <= 20) and func4) or func5 in ("Nothing","Sonething") or (func1 + func2_z) > 2*func3)'

code = compile(expression, "<string>", "eval")

r = eval(code, eval_parameters)

print(r)
→ Ссылка