Я интерпретирую этот вопрос как «моя injson
структура данных содержит серию объектов, которые представляют компоненты выражения. Как я могу оценить это выражение и вернуть окончательный результат?»
Грамматика вашего языка выражений выглядит довольно просто: каждый компонент представляет собой либо простое значение, такое как «yang», либо словарь, представляющий вызов функции. Таким образом, ваш рекурсивный оценщик должен обрабатывать только эти два случая. Большая часть реальной работы будет заключаться в переводе ваших пользовательских операторов в нечто, понятное Python.
Пример реализации:
import operator
def check_type(obj, type_name):
#we can't just directly use `isinstance` for type checks, because `isinstance("foo", "string")` doesn't understand what the second argument is supposed to represent.
#so we need an extra layer here to convert type-looking strings into actual types.
types_by_name = {"string": str, "int": int, "bool": bool} #add more types as desired
return isinstance(obj, types_by_name[type_name])
operators_by_name = {
"gte": operator.ge,
"startswith": str.startswith,
"type": check_type,
#add more named functions as desired
}
def eval_json(obj):
if isinstance(obj, dict) and "$op" in obj:
op = operators_by_name[obj["$op"]]
args = [eval_json(arg) for arg in obj["$params"]]
return op(*args)
else:
return obj
injson = {
"$op": "gte",
"$params": [
{
"$op": "startswith",
"$params": ["yang", "y"]
},
{
"$op": "type",
"$params": ["yang", "string"]
}
]
}
print(eval_json(injson))
Результат:
True
Это желаемый результат, поскольку "yang".startswith("y") >= isinstance("yang", str)
также имеет значение True.