LINUX.ORG.RU

Организация типизированных (в т.ч. типы пользователя) данных с комментариями в json?

 ,


0

6

Сабж.

В python есть pickle который хранит в т.ч. типы пользователя и автоматически импортит модули при десериализации, но pickle какой то маргинальный стал (чехарда с форматами и невнятные перспективы), хочется уйти на json. Кроме того pickle все равно не умеет хранить комментарии из коробки.

Нужно сохранять и загружать вот такое:

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

  2. ключи в исходных данных гарантированно текстовые отвечающие требованиям к питоньим идентификаторам.

  3. Типы параметров — все что есть в json из коробки (числа, строки, списки, словари) + что то пользовательское, м.б. сложное и требующее импорта сторонних модулей при восстановлении.

  4. некоторые из параметров могут быть снабжены комментариями (комментарий это строка)

  5. желательно что бы комментарий лежал рядом с параметром для улучшения читабельности .json - файла глазами.

Интересна не техника записи/чтения в коде, интересна сама структура данных.

Понятно что список импортируемых модулей можно хранить в каком то списке на верхнем уровне.

Можно сделать две параллельных структуры с типами и комментариями, но выглядит как извращение:

[{ 'a':1, 'b':2.5, 'c':[1,2,3]},
 {'c':'myvector.myvector3D'},
 {'a':'длина баскетбольной площадки', 'c':'куда бросать мяч'}
]

Можно загонять тип в имя параметра 'myvector3D c':[1,2,3], можно рядом с параметром класть какую то информацию '@c':['myvector3D', 'куда бросать мяч'] — но это все работает только если параметры лежат в словаре, скорее всего так и будет но что то может поменяться.

В общем много вариантов но хороших я не вижу;-(

@annulen

★★★★★

Последнее исправление: AntonI (всего исправлений: 1)

Для сер/десер обычно массив кладут, где первым параметром тип. Типа { a: ["mytype", "A"]}

ya-betmen ★★★★★
()
Ответ на: комментарий от AntonI

Сейчас я понимаю что выбор был прямо скажем не айс, особенно с учетом тендценций развития питона и постоянным сломом обратной совместимости.

Надо же, прозрение наступает

Psilocybe ★★★★
()
Ответ на: комментарий от maxcom

JSON убог. Один Number че стоит, я когда с финансами работает, наелся с ним говна

Да и вообще, что значит зачем? Зачем вообще нужны разные форматы данных? Зачем нужны разные ЯП когда есть оптимизированный Фортран?

lovesan ★★
()
Ответ на: комментарий от dmitry237

Машинам комментарии не нужны, при изменении json они их просто удалят, разработчикам легче записать новый файл, чем изменять существующий. Если конечно они не предусмотрели личные комменты.

Это формат, который читают машины и пишут машины. Просматривать файл имеет смысл только с точки зрения отладки. А оставлять комментарии, которые есть только в файле – очевидное повреждение мозга.

Хочется читать этот файл, добавлять туда комментарии – выбор другого формата поможет.

thegoldone ★★
()
Ответ на: комментарий от Psilocybe

И занимают такие комменты место после загрузки в прогу.

Эти комментарии для того, чтобы их загрузить и показать пользователю (в удобном виде). А не для того, чтобы читать их из файла. Если не нужно их загружать, то это делается пропуском поля. Некоторые известные мне парсеры умеют так делать.

thegoldone ★★
()
Ответ на: комментарий от lovesan

Один Number че стоит, я когда с финансами работает, наелся с ним говна

В JSON Number – это произвольное число с некоторыми ограничениями. А то, что некоторые парсеры превращают его в IEEE 754-1985 double – ну так это проблемы этих парсеров. И да, их навалом таких нехороших.

thegoldone ★★
()
Ответ на: комментарий от Shushundr

Внезапно бинарные форматы хрупки, сложеый в отладке и плохо переносимы между разными платформами

AntonI ★★★★★
() автор топика
Ответ на: комментарий от thegoldone

Какие оправдания не придумают, лишбы xml не пользоваться.

Psilocybe ★★★★
()
Ответ на: комментарий от thegoldone

Просматривать файл имеет смысл только с точки зрения отладки

Не согласен. А как же управлять приложением, например из скриптов? А комменты для той же отладки и нужны, особенно когда названия опций не отражают их смысл:

{
     "name": "abcd-ef-9999",
     "comment": "эта опция нужна для того-то"  // Этот "comment" пользователя удалится программой при перезаписи файла
}
dmitry237 ★★★★
()

Храни данные в json (файлы или бд, можно sqlite). Для конвертации в питоновские объекты и наоборот есть чудесный pydantic с валидацией всего и вся.

skyman ★★★
()
Ответ на: комментарий от AntonI

Но не все, а некачественно задизайненные.

Интернет бинарные пакеты бинарно передаёт и всё у него хорошо с переносимостью между разными платформами.

Shushundr ★★★★
()

но что то может поменяться

Вот прям да. Потому задача изначально странная. Вам в первую очередь нужно строить модель и версионирование/миграции, а как её хранить - дело десятое. Можно хоть вообще протобуф в файлы писать

upcFrost ★★★★★
()
Ответ на: комментарий от Shushundr

Если бы это было так, то формат был бы бинарный. Но нет, он текстовый.

Он текстовый, потому что скриптота. JS вообще очень долго не умел в бинарные данные. Не факт, что и сейчас умеет нормально.

Как будто XML человекочитаемый. А ведь он тоже текстовый. И таких форматов валом.

thegoldone ★★
()
Ответ на: комментарий от thegoldone

JS вообще очень долго не умел в бинарные данные. Не факт, что и сейчас умеет нормально.

так ты безграмотен? ОК, записал.

Eulenspiegel
()
Ответ на: комментарий от thegoldone

Возьмите другой формат и транслируйте его в JSON

Мне-то это зачем? Пусть об этом думают разработчики, если им удобен JSON, то ничего против этого сказать не могу. Главное, чтобы можно было менять параметры запущенного приложения напрямую через конфиг, а не через GUI.

dmitry237 ★★★★
()
Ответ на: комментарий от thegoldone

Для кого не значит? Для пользователя главное, чтобы был формат, удобный для обработки. Хоть с помощью dconf менять настройки приложения в реальном времени, не вызывая гуй-меню. Json, как формат конфига, позволяет это делать достаточно просто.

dmitry237 ★★★★
()
Ответ на: комментарий от dmitry237

С точки зрения формата конфига JSON не очень хорош - очень много лишних символов и дурацких ограничений. TOML как конфиг несколько лучше.

Я же (видимо) хочу что бы все сразу было в одном и что бы за это ничего не было;-)

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

TOML (и YAML) меня тоже устраивает, а вот INI нет, его надо парсить, как обычный текстовый файл, может я просто не знаю, чем их обрабатывают. Я конечно могу написать костыльный скрипт, который преобразовывает INI в объект, но это до сих пор не понадобилось.

dmitry237 ★★★★
()
Последнее исправление: dmitry237 (всего исправлений: 1)

Смотри json хорош тем что прост и везде поддерживается. В теории TOML удобнее для человека, но поддержка сильно хуже. pickle это костыль, не надо его в конечный продукт за пределы какого-то экспериментального скрипта для очистки данных, который никогда не покинет компьютера разработчика, большая дыра в безопасности. Его единственное применение (как я вижу) это в каком-нибудь юпитере при анализе данных которые медленно обрабатывать быстро какие-то промежуточные результаты сохранять, чтоб когда алгоритм меняешь и пробуешь другие варианты по 5 часов одно и то же не пересчитывать (а пробовать и дорабатывать иногда по 20-30 раз приходится прежде чем получиться что-то что будет на 1% лучше чем что-то что уже кто-то опубликовал даже если область не очень хорошо изучена и плохо формализована, понятно что там где хорошо изучена и формализована там вообще немного иначе надо работу организовывать).

peregrine ★★★★★
()
Ответ на: комментарий от AntonI

Хранение результатов расчетов. С одной стороны расчеты разные (со временем даже расчеты по одному и тому же проекту могут меняться), поэтому нужны комменты.

Бери git для этого и пихай туда json-ы и комменты пиши в гит. Я вообще как правило любой коммит с метки начинаю в своих проектах по типу

fix: fixed color palette bug
feat: added gaussian blur alghoritm
data: text representation changed from 2-grams to 3-grams

Коммиты конечно условные. В каждом проекте есть файл где описаны возможные метки, data есть далеко не везде.

ЗЫ

Ещё можно в субд данные пихать и часто там же и обрабатывать средставми sql. sql в postgre рвёт питон как тузик грелку на больших структурированных данных в плане производительности. Всякие скулайты могут не рвать.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от dmitry237

Хоть с помощью dconf менять настройки приложения в реальном времени, не вызывая гуй-меню.

Интересно, при чём тут dconf и GUI с одной стороны. И комментарии в JSON с другой.

Json, как формат конфига, позволяет это делать достаточно просто.

Что делать? JSON это вообще не для человека формат. Как и что он позволяет менять в каких-то программах – не имеет значения.

thegoldone ★★
()
Ответ на: комментарий от peregrine

Бери git для этого и пихай туда json-ы и комменты пиши в гит.

Вообще мимо кассы.

Ещё можно в субд данные пихать и часто там же и обрабатывать средставми sql.

Это и так субд, только не реляционная. на реляционную модель это ложится плохо.

AntonI ★★★★★
() автор топика

Минуточку. Мы про жсон или про организацию типизированных данных с комментариями?

Нафиг пикль, бери тикль. Да-да, это ещё и формат данных. Объясняю. Структура примерно следующая. Всё есть строка, но строка с разделёнными пробелом элементами может интерпретироваться в качестве списка. Конкретно в твоём случае формат предлагаю следующий:

{a 1 b 2.5 c {1 2 3}}

Но где же типизец? А вот где — расширяем так:

{
 {a myvector.vector3D {длина баскетбольной площадки}} 1
 {b float} 2.5
 {c list {куда бросать мяч}} {1 2 3}
}

То есть тиклевский словарь {key1 value1 key2 value2...}, который по сути является списком с определённым правилом размещения элементов, берём и расширяем до ключей в виде списка из строк. Проблема решена. Парсер для такого пишется элементарно, даже если готового нет.

rebforce
()
Последнее исправление: rebforce (всего исправлений: 1)
Ответ на: комментарий от thegoldone

JSON это вообще не для человека формат

Я же уже объяснил. Если приложение конфигурируется через конфиг, то не важно в каком он формате, главное чтобы его было удобно обрабатывать. В alacritty, например, измение конфига (toml), это штатный способ конфигурации. TOML, это для человека?

Что делать?

Обрабатывать файл в формате JSON.

Как и что он позволяет менять в каких-то программах – не имеет значения.

Для вас может и не имеет, и что из этого? Всем отказаться от такой возможности или необходимости?

dmitry237 ★★★★
()
Ответ на: комментарий от dmitry237

В alacritty, например, измение конфига (toml), это штатный способ конфигурации. TOML, это для человека?

Кстати забавно, что раньше конфиг у них был в YAML, но задолбались бороться с ошибками из-за неправильных отступов:

https://github.com/alacritty/alacritty/issues/6592

I’m quite honestly tired of looking at YAML files with broken indentation.

Ja-Ja-Hey-Ho ★★★★★
()
Ответ на: комментарий от Ja-Ja-Hey-Ho

Да, скорее всего, пользователи правят конфиг в редакторе, а там и до ошибок не далеко. Хотя вроде alacritty показывал синтаксические ошибки. Но пользователь склонен не исправлять, а сразу жаловаться в issue’s tracker.

dmitry237 ★★★★
()
Ответ на: комментарий от rebforce

Хотя если это делать нативно на самом тикле, то я бы формат даже слегка докрутил до такого, чтобы dict всё-таки ключ в виде одной строки видел:

{
 a {myvector.vector3D {длина баскетбольной площадки} 1}
 b {float {} 2.5}
 c {list {куда бросать мяч} {1 2 3}}
}

Но тогда да, придётся пустые комментарии тоже хранить (в виде {}). Но суть от этого кардинально не изменится. В принципе, то же можно переписать на JSON, но читабельность пострадает. А здесь и машине, и человеку норм.

rebforce
()
Последнее исправление: rebforce (всего исправлений: 1)
Ответ на: комментарий от rebforce

Человеку все таки норм когда нет лишних скобочек. У нас принят сейчас вот такой конфиг для простых случаев

key value # comment

один параметр в одной строке. Значение может быть из нескольких величин разделенных пробелом.

Если к этому приделать тип (перед комментом с каким то магическим символом в начале) то будет норм. Правда остается вопрос как выделять строки-значения (редко но бывают) — кавычками? cкобками? все что не число то строка (как ловить ошибки)?

Второй вопрос - как туда же пихать что то более структурированное, типа списков/словарей. Скорее всего если значение открывающая скобка то это уже словарь/список, что бы закрыть его нужна отдельная (одна на строку) закрывающая скобка.

Я еще понял что полностью согласен с предыдущими ораторами что для машины удобен другой формат. Поскольку это нереляционная база и у нее есть кэш, то вот кэш будет хранится в чем то своем, видимо бинарном и пошустрее, хоть в том же pickle. Кэша не жалко, он инкрементальный, его на лету один фиг перегенерируют/апдейтят, если ему формат поменять никто не заметит.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

Человеку все таки норм когда нет лишних скобочек.

Вместо скобочек можно кавычки. Например, комментарии брать в кавычки, а списки — в {}. Тут универсальность в том, что можно хоть в одну строку, хоть по одному значению на отдельной строке — суть та же.

Правда остается вопрос как выделять строки-значения (редко но бывают) — кавычками? cкобками?

Оба. В тикле (формате данных) {this is a string} и "this is a string" идентичны, просто в тикле (языке) во втором случае внутри будут обрабатываться подстановки команд и переменных. Но в кастомном парсере ничто не мешает так не делать.

Второй вопрос - как туда же пихать что то более структурированное, типа списков/словарей.

Так я ж написал выше, как. Список это или словарь — определяется на уровне логики приложения, на уровне формата это просто строки через пробел. Я вон раньше модуль inifile из tcllib подключал, а потом для своего ii-клиента подумал: зачем? Читаем файл и dict уже с ним как есть может работать по сути. Даже в предложенной тобой структуре, покуда # всегда отделяется пробелом, можно считать это тоже специальным ключом, который просто не обрабатывается логикой. Но значение после него должно группироваться скобками/кавычками, типа:

simplekey simplevalue # "this is a comment"
"some long key" {type list elem1 elem2 elem3} # "this is also a comment"
"compound key" { # "this will be a compound object"
 type dict # "declaring an internal type"
 innerkey1 innerval1
 innerkey2 100500
}

Стоит ли усложнять парсер ради убирания «лишних» кавычек и скобок, смотри сам.

rebforce
()
Ответ на: комментарий от thegoldone

Мне лень разбираться

Вас к этому никто не принуждал, лень так лень.

dmitry237 ★★★★
()
Ответ на: комментарий от thunar

А чем, собсно, плохи S-выражения? Хотя здесь семантика слегка другая: здесь ничего не эвалится ни по умолчанию, ни вообще. Скобки/кавычки только для группировки вложенных строк применяются.

rebforce
()

pickle какой то маргинальный стал (чехарда с форматами и невнятные перспективы)

А что у него с перспективами? Его максимум из стдлибы могут выбросить во внешний пакет. И вероятность что так сделают почти нулевая.

Версию протокола всегда можно зафиксировать. Либо просто не использовать нигде древние питоны.

Какие-то надуманные проблемы и изобретение колеса, чтобы вот неприятный пикл не использовать. Какие перспективы у твоего формата и не будет ли там чехарды?

neumond
()

Мне здесь видятся два совершенно разных юз-кейса:

  1. Входные файлы для расчётов, редактируемые пользователями. Если мы даём возможность пользователям комментировать всё подряд, то это уже строго говоря не является форматом сериализации (комменты потеряются при загрузке), и тут всё обязательно должно быть текстом. Здесь я бы использовал текстовые форматы, которые уместно применять для конфигурационных файлов с неограниченной вложенностью: YAML, libucl, мб. упомянутый JSON5 (если не тошнит от большого количества знаков препинания). Как вариант, если не страшно загружать непроверенные данные на Тюринг-полный языке - питоновые словари или Lua-таблицы.
  2. Собственно, «хранение результатов расчетов». Тут вполне уместно выглядел бы бинарный формат, особенно если результатов много. Я бы использовал CBOR, а в случае необходимости поглядеть глазами на содержимое переводил бы его в JSON. Что касается комментариев, то их можно хранить в текстовом формате в соседнем файле (если хочется удобно редактировать и читать) или в специальном поле внутри CBOR (если принципиальна целостность)
annulen ★★★★★
()
Ответ на: комментарий от annulen

В итоге я сейчас комментарии храню в отдельном файле в формате json. В тот же файл класть пробовал, но по ряду причин не зашло. В частности потому что файл от этого раздувает больше чем вдвое, а для скорости загрузки это важно.

Меня сейчас другое одолевает, коллеги в соседнем проекте аналогичную штуку сделали на mongodb. Вот теперь думаю переходить/не переходить…

И да, все таки кофиги юзеров это отдельный формат.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

Переходить на монгу стоило 10 лет назад, а сейчас это уже умершая технология)

annulen ★★★★★
()
Ответ на: комментарий от annulen

Не, реляционная БД тут точно ненужна.

Готовые решения интересны тем что у них какое то гуи есть и устоявшаяся идеология - с другой стороны у меня и так уже все работает, а простенький гуи при большом желании наверное проще самому сделать, чем все перелопачивать под другую систему?

Чего вот наверное не хватает - общего списка коллекций (в терминах монго) по каждой задаче, а то через год не вспомнишь что где считал. Если несколько человек работало то вообще труба… Но опять таки, это на коленке сделать несложно.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от MOPKOBKA

Но эти жсоны в таблице лежат. Напуркуа тащить СУБД что бы щавести в ней одну таблицу с одним столбцом?!

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Напуркуа тащить СУБД что бы щавести в ней одну таблицу с одним столбцом?!

  1. Столбец там явно будет не один. Как минимум, будет ещё timestamp, кто делал и краткое описание. И мб название проекта, если расчёты для разных проектов хранятся вместе. База заводится не для того, чтобы было легко добавлять данные, а для того, что было легко найти.
  2. Как подсказали выше, можно делать выборки по полям из жсона, но при надобности можно даже индексы по этим полям построить.
  3. В выборке можно трансформировать JSON’ы средствами постгреса
annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.