Comments 62
— можно ли запихнуть XML в AXON?
— можно ли запихнуть JSON в AXON?
У нас системы общаются на базе AXON и нам нужно прокинуть в еще одну нашу систему XML (или JSON), который получили от пользователя.
Да, можно.
XML без пространств имен можно также по ходу преобразовать в AXON. Для этого достаточно прочитать его, например, при помощи etree или lxml.etree и вставить получившийся объект с именем, скажем xml. Зарегистрировать reducer для типов XmlElement, XmlDocument, XmlAttribute. Затем во время dump-инга он преобразуется в представление в нотации AXON. Если зарегистрировать factory функциию для элемента xml, то после загрузки вв соответствующем месте будет XmlDocument.
1. Можно-ли без кавычек использовать любой ключ? Например "$3ухлкйл Фр94нк, хи7 3"? Если да, то как это добавит удобочитаемости?
2. Чего именно я достигну используя AXON вместо JSON? Каковы преимущества, кроме представления структур в стиле python-way? Я не заметил в статье ответа на этот вопрос, т.к. описанные неудобства JSON надуманны.
Без кавычек можно только идентификаторы.
Необходимость всегда использовать кавычки, как показал мне интернет — не совсем надуманные, впрочем единого мнения тут нет. Что касается запятых, то они, вообще говоря, не обязательны.
Для ответа на второй нужно было бы подробнее описать возможности библиотеки. Но для этого скорее всего получится еще одна статья.
Если кратко, то, например, можно отображать именованные элементы в объекты. Для этого регистрируется функция для его создания.
Пример приведен в ответе для amaksr
.
В JSON не гарантируется, что после загрузкиНе верно. В описании json'а лишь говорится:
{ «name»: «Alex»,
«birth»: «1979-12-25»,
«email»: «mail@example.com»}
порядок ключей/атрибутов сохранится.
An object is an unordered set of name/value pairs.
А порядок при маппинге зависит от библиотеки. В той же java, если мапить объект на
LinkedHashMap
, то порядок сохранится.В статье затронут только аспект самой нотации как способа текстового представления объектов.
Разные типы объектов использовать можно. В библиотеке pyaxon есть возможность отображать классы на именованные структурные объекты. Например, можно отобразить
person { name: "Иванов" age: 30 }
на namedtuple
, определив:
text = """
person { name:"Иванов" age:30 }
"""
Person = namedtuple("Person", "name age")
@axon.factory("person")
def Person_factory(attrs, vals):
return Person(**attrs)
vals = axon.loads(text, mode="strict")
print(vals[0])
Определение типа для всего списка AXON и библиотека pyaxon
пока еще не поддерживает.
axon
name: "AXON is eXtended Object Notation"
atomic_values
string: "abc абв 中文本"
multiline_string: "one
two
three"
date: ^2012-12-31
первый вопрос на котором себя словил: three" — почему тут есть кавычки? это какая-то специальная пометка?
не сразу заметил, что это конец строки.
мимо
Просто текст, заключенный в кавычки может состоять из нескольких строк.
И если на такие грабли можно наступить на столь элементарном примере, то на более сложном это может вылиться в множество потраченных минут / часов на поиск проблемы.
Вложите более-менее сложный YAML документ, как многострочное поле в AXON документе, который в свою очередь представлен в виде YAML, это вполне валидный кейс:
— вы записываете в файл данные, пришедшие извне, в формате AXON в представлении YAML, для удобства чтения.
Шутки про вложение XML в JSON (или даже JSON в JSON) смешные, пока не столкнешься с ними в реальном проекте.
Ну может получиться нечто вроде этого:
..............
config: "
option1: \"asdasdsadsd\"
option2: \"erwrwetrter\"
option3: \"vcnbnbmv\"
"
............
Для этих целей преудсмотрена альтернатива:
..............
config: `
option1: "asdasdsadsd"
option2: "erwrwetrter"
option3: "vcnbnbmv"
`
............
Символ ` конечно нелегко заметить, может имеет смысл заменить его ```.
имена атрибутов/ключей, которые являются идентификаторами приходится заключать в кавычки;
легко забыть запятую в случае вставки новой пары ключ: значение.
Это вы оригинальничаете или просто не в теме? Вторым пунктом ВСЕГДА идет отсутствие комментариев и не надо ничего придумывать. Запятую они могут забыть… Надо изучать матчасть перед началом разработки:
JSON, который можно комментировать
KTV. Новый JSON
JSON для любителей скобочек
Усложнённый упрощённый JSON
Universal Binary JSON — ещё один бинарный JSON
jsonex – упрощаем сложные клиент-серверные диалоги
JSON с комментариями (github, внизу смотреть список аналогичных проектов)
Tree — убийца JSON, XML, YAML и иже с ними — однозначно рекомендую комменты к прочтению
Комментарии в AXON имеются в стиле python.
Претензию на оригинальность можно было бы принять, если бы AXON претендовал на оригинальность. Это эксперимент, возможно удачный, возможно не очень.
Что касается YAML'а, то мне как-то не нравятся пробело-табо-зависимые форматы. С другой стороны, yaml уже есть, зачем пытаться совместить все сразу?
В первоначальной версии форматирования в стиле YAML отсутствовало. Оно было добавлено как возможность.
Принципиальное отличие от JSON в том, что AXON имеет именованные элементы.
Что касается JSON 2.0, то он принципиально привязан в синтаксису javascript. И скорее всего, придется ждать пока все перечисленное не появится в формате JSON как части javascript.
JSON имеет два неудобства:
- имена атрибутов/ключей, которые являются идентификаторами приходится заключать в кавычки;
- легко забыть запятую в случае вставки новой пары ключ: значение.
AXON устраняет эти неудобства следующим образом:
- можно не заключать в кавычки имена, которые являются идентификаторами;
- совершенно опускаются разделительные запятые, используются только пробельные символы для разделения элементов.
JSON имеет куда более неприятные особенности, чем приведенные в статье.
Как вариант, в JSON необходимо каждый раз указывать все имена полей в массиве однотипных объектов. Из-за этого объем json документа существенно увеличивается.
Убрать кавычки, если ключ имеет вид идентификатора — это существенное усложнение парсера, которое позволит сэкономить 20 символов для строки длинной в 300 символов.
К тому же из документации не понятно, можно ли кавычку " или какой-то спец.символ использовать как Ключ, как вариант для конфигурации автозамены.
Как вариант, в JSON необходимо каждый раз указывать все имена полей в массиве однотипных объектов
Зачем?
[{"name": "A", "score": 90}, {"name": "B", "score": 80}, {"name": "C", "score": 70}, {"name": "D", "score": 60}]
Можно обойти, задав жесткий контракт:
[["A", 90], ["B", 80], ["C", 70], ["D", 60]]
Но семантика уже не та.
Но семантика уже не та
А как на счет:
{
"type": ["name", "scope"],
"collection": [["A", 90], ["B", 80], ["C", 70], ["D", 60]]
}
Но теперь нужно писать encoder / decoder для этого формата во всех частях системы на всех языках, которые в нашей системе будут и нам очень повезет, если у нас будет язык со слабой типизацией.
Но это уже трейдоф: решили проблему объема данных, заплатили написанием кастомного парсера.
А можно так:
data {
type: ("name" "scope")
("A" 90)
("B" 80)
("C" 70)
("D" 60)
}
@axon.factory("data")
def data_factory(attrs, vals):
name, scope = attrs["type"]
tp = get_type_factory(name, scope)
return [tp(args) for args in vals]
Кстати, семантически ваш пример, это Node, Dict, Set или что?
Строка из одной кавычки будет записана как "\""
Для массива из однотипных объектов можно было бы предложить, например, такое решение:
persons {
{name: "Иванов" age: 30}
{name: "Сидоров" age:33}
}
@axon.factory("persons")
def persons_factory(attrs, vals):
return [Person(**val) for val in vals]
vals = axon.loads(text, mode="strict")
print(vals)
В результате получим
[[Person(name='Иванов', age=30), Person(name='Сидоров', age=33)]]
В JSON не гарантируется, что после загрузки
{ "name": "Alex",
"birth": "1979-12-25",
"email": "mail@example.com"}
порядок ключей/атрибутов сохранится.
В AXON констатируется, что
[ name: "Alex"
birth: ^1979-12-25
email: "mail@example.com"]
преобразуется в mapping с сохранением порядка ключей.
В JSON тоже можно массивы.
[ name: "Alex"
birth: ^1979-12-25
email: "mail@example.com"]
это не массив
[ ["name", "Alex"], ["birth", "1979-12-25"], ["email", "mail@example.com"] ]
или:
[ {"name": "Alex"}, {"birth": "1979-12-25"}, {"email": "mail@example.com"} ]
в зависимости от предпочтений, технических возможностей и ограничений.
При этом использовать стандарт разметки, которы поддерживается во всех языках и давно отлажен и отлично работает.
Да можно, но при этом усложнится обработка такого массива.
В данном случае просто есть встроенная возможность получить словарь (ordered dict).
Кстати нотация для ordered dict была добавлена по предложению одного пользователя. Для него это было важно.
Стандарты время от времени меняются.
Да, это инерция и ретроградство. Но даже если AXON однозначно не хуже JSON в любом возможном случае, вокруг второго-то уже есть инфраструктура и он свои задачи решает. За очень редким исключением замена JSON на что бы то ни было ещё будет починкой несломанного, ИМХО.
Никто не ожидает того, что AXON или любой другой формат сразу заменит JSON. Вспомните сколько прошло времени для того, чтобы JSON API стали включать наравне с XML API.
Чтобы быть более точным, если AXON и стоит использовать, то только в новых проектах.
Важны, если используется стиль форматирования для именованного элемента в духе YAML. Например:
person { name:"Иванов" age:30 }
здесь не важны, но для
person
name: "Иванов"
age: 30
важны.
Для списков, словарей, множества, кортежа — не важны, так как для них не предусмотрен стиль форматирования в стиле YAML.
А в чём конкретный профит?
Я к тому, что для конфигов есть yaml и HOCON (и насколько я вижу axon — heavily inspired by HOCON), а если для трансфера объектов, то читаемость отходит на второй план и на первое место выходит объём данных и производительность парсеров + возможность потокового разбора, о чём в статье ни единого слова нет.
AXON не имеет отношения к HOCON.
Для трансфера в AXON не нужно использовать форматирование с табами и отступами. Тогда получится компактная форма.
Статья увы неполная.
По поводу профита. AXON главным образом создавался для текстовой сериализации. Писать конфиги можно, но это не имелось ввиду, так как считаю что YAML вполне подходит для этого.
Раз для сериализации, то можно немного статистики по скорости сериализации/десериализации + средний объём данных в сравнении с JSON и MessagePack (понимаю, что последний — бинарный формат, но AXON тоже так умеет, так что было бы интересно посмотреть) + вы так и не ответили на вопрос про потоковую сериализацию/десериализацию.
AXON это текстовая нотация для представления данных (текст в формате unicode). Сообщение AXON представляет последовательность значений или последовательность пар ключ:значение
. Поэтому читать из потока и писать в поток каждое значение или пару ключ: значение можно итеративно в отличие от JSON.
Есть несколько тестов сравнения скорости загрузки/дампа с JSON. Дамп отстает от JSON в среднем на 10-15%, загрузка в среднем на 20-50% (по моим наблюдениям эти цифры можно немного уменьшить). Естественно, что скорость загрузки/дампа в случае JSON будет быстрее, так он имеет более простую структуру. Однако при загрузке/дампе очень больших последовательностей данных AXON выигрывает из-за того, что не нужно сначала строить всю последовательность в памяти. Сравнение производительности проводилось для реализации pyaxon и модуля json
из стандартной библиотеки версии 3.5. Для более ранних версий python (2.7 — 3.4) процентные величины меньше (в python 3.5. производительность json заметно улучшена).
Сравнение с MessagePack не производилось, так как из общих соображений ясно, что производительность для сообщений, содержащих числовые данные будут кодироваться и декодироваться существенно быстрее в MessagePack, посколько AXON является текстовым форматом. Так что сравнивать имеет смысл только сообщения, содержащие структурированный текст.
Однако при загрузке/дампе очень больших последовательностей данных AXON выигрывает из-за того, что не нужно сначала строить всю последовательность в памяти.
В большинстве парсеров JSON-a используется потоковая обработка (по крайней мере в яве), так что этот выигрышь мимо кассы.
Совершенно не понял: чем AXON лучше, чем YAML?
Как предполагается решать определение типов объектов (в JSON — доп. поле, в YAML — тэги, в XML — пространства имен, в AXON — ?)?
В AXON как в XML можно использовать элементы с именами/тегами.
В библиотеке pyaxon
используется механизм регистрации порождающей функции по имени элемента.
Для примера см. комментарий
Я не ответил на вопрос: чем AXON лучше, чем YAML.
AXON создавался как нотация для текстового представления объектов/данных, который бы, по возможности, объединил достоинства JSON, XML и YAML, а также по возможности избежал их недостатков. Если не всех, то основных.
Поэтому говорить, что YAML хуже чем AXON или наоборот некорректно.
Кстати: [] — это пустой list или ordered dict ?
Что такое AXON