#python #json #validation #parsing #recursion
#python #json #проверка #синтаксический анализ #рекурсия
Вопрос:
Используйте Python для разбора json в соответствии с его операцией
это мой входной json
injson = {
"$op": "gte",
"$params": [
{
"$op": "startswith",
"$params": ["yang", "y"]
},
{
"$op": "type",
"$params": ["yang", "string"]
}
]
}
я хочу получить out, но я хочу реализовать с помощью функции
out = "yang".startswith("y") >= isinstance("yang", str)
print(out)
«startswith», «type», «gte» возвращают логическое значение
$ op — это то, что нужно сделать opereate, $ params — это параметры со списком, может быть много слоев, я хочу написать рекурсивную функцию для ее реализации, используя python
Ответ №1:
Я интерпретирую этот вопрос как «моя 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.