Использовать (JSON или YAML) сгенерированные значения данных в Python - PullRequest
1 голос
/ 25 мая 2020

Я пытаюсь найти способ представления типов данных в JSON или YAML, на которые можно ссылаться в других файлах JSON / YAML для определения других объектов, которые затем могут быть обработаны в файле Python.

Любые советы по другим технологиям, которые могут удовлетворить мои требования, также будут оценены.

Исходя из моего базового c понимания:

  • JSON схемы позволяют вам ссылаться на другие JSON схемы с помощью команды $ ref, это определяет типы поле, но не значения.

  • YAML позволяет использовать якоря и флаги для ссылки только на значения данных в ОДНОМ файле.

Мне нужна их смесь. - Для компоновки моих данных с элементами типов, определенных в других файлах. - Чтобы иметь доступ к данным, указанным в типе.

Изначально у меня есть сторонний python файл с настройками, и он может быть изменен.

Например (игнорируя любые очевидные синтаксические ошибки):

3rdParty.py

alpha.beta.LOW = 1
alpha.beta.MEDIUM = 2
alpha.beta.HIGH = 3

, из которых я автоматически генерирую vars. json file:

[
  {"LOW" : "alpha.beta.LOW"},
  {"MEDIUM": "alpha.beta.MEDIUM"},
  {"HIGH": "alpha.beta.HIGH"}
]

Сконструирован foo. json файл

[
  "construct_1":
    {"A": "vars.json#/LOW"},
    {"B": "something"},
    {"C": "vars.json#/MEDIUM"},
    {"D": "something"},
    {"E": "vars.json#/HIGH"}
  },
  ... construct_2 / construct_3 defined ...
]

Сконструирован bar.py файл

import json

data = json.load('foo.json')
setting = eval(data.construct_1.A)        # resolves to alpha.beta.LOW or 1           

Возможно ли это и как?

Большое спасибо.

1 Ответ

1 голос
/ 25 мая 2020

Что касается JSON, "$ref" - это не команда, а просто строка. Это реализация схемы JSON, которая присваивает ей семанти c.

JSON и YAML - это языки, которые описывают структуры данных, не больше и не меньше. У них нет команд. Если вы их используете, вы можете делать с загруженными данными все, что захотите, но вам нужно реализовать это самостоятельно. Причина, по которой YAML имеет якоря и псевдонимы, заключается в том, что он сериализует график, а JSON сериализует дерево.

YAML предоставляет теги , которые вы можете использовать для определения значений, которые необходимо заменить, например,

construct_1:
  A: !ref "vars.json#/LOW"
  B: "something"
  C: !ref "vars.json#/MEDIUM"
  D: "something"
  E: !ref "vars.json#/HIGH"
construct_2: # …

Как видите, я пометил все значения, которые необходимо разрешить, тегом !ref. Теперь вам нужно реализовать этот тег:

def resolve_ref(loader, node):
  path = loader.construct_scalar(node)
  return resolve_path(path)

yaml.add_constructor(u'!ref', resolve_ref)

Для этого необходимо реализовать resolve_path. Если вы сделаете это правильно, вы можете сделать

data = yaml.load("foo.yaml")
setting = eval(data["construct_1"]["A"])

, и он будет оценивать все resolve_path разрешенные vars.json#/Low в.

...