используйте рекурсивную функцию python для разбора json с некоторым регулированием

#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.