Pull to refresh

Comments 47

Мой любимый пример:


>>> from json import dumps
>>> example={"json": ["it's", "simple"]}
>>> one={"one": json.dumps(example)}
>>> two={"one": dumps(one)}
>>> three={"three": dumps(two)}
>>> dumps(three)
'{"three": "{\\"two\\": \\"{\\\\\\"one\\\\\\": \\\\\\"{\\\\\\\\\\\\\\"json\\\\\\\\\\\\\\": [\\\\\\\\\\\\\\"it\'s\\\\\\\\\\\\\\", \\\\\\\\\\\\\\"simple\\\\\\\\\\\\\\"]}\\\\\\"}\\"}"}'

Сравните с форматированием в yaml:


three: |
  two: |
    one: |
      example: |
        yaml:
          - it's
          - simple

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

Согласен, в моём случае — чаще всего, когда YAML лучше JSON, это Важные и Ответственные конфиги. Сколько раз ансибл падал, просто потому что там три пробела вместо двух — не пересчитать.
Слева ошибка, и справа ошибка
image

Но слева она невидима.

меня таб смущает (или что-то странное с пробелами). Плюс неэкранированное двоеточие.

Вот это и есть минус ямла. Вроде «для людей», но фактически:
1. Нет там табов слева, в принципе.
2. С двоеточием всё в порядке.

Вот так сидят учёные мужи и гадают, почему человек не может найти ошибку в «человекочитаемом» формате.

На самом деле перед command не хватает одного пробела, всё, это единственное место с ошибкой.
Вот так сидят учёные мужи и гадают, почему человек не может найти ошибку в «человекочитаемом» формате.

так правильно. Потому что YAML НЕ НУЖНО редактировать. Его нужно генерировать и давать читать людям. В этом случае действительно проблемы нет, потому что содержимое будет валидное (т.к. оно сгенерировано) и глазу приятно смотреть.
Но редактировать — хуже (по озвученным Вами причинам) формата нет

Таких ситуаций быть не может, потому что любой json — это валидный yaml. Обратное не верно.

Любой base64 текст — валидная utf-8 последовательность. Обратное не верно.
Так вот, я утверждаю, что зачастую base64 лучше, чем utf-8.
И да, такая ситуация ещё как может быть.

В том месте, где удобнее, вы пишите base64 и работаете с ним как с utf-8. У yaml то же самое. Если вам где-то удобнее вписать на json (роботы, например), то парсить это вы можете по-прежнему yaml'ом. (И тут аналогия с utf-8 рассыпается, потому что при парсинге yaml вы получите те же структуры, что и при парсинге json).

Чтобы писать на ямле. Это проще, чем на json'е.

Ну, такое… Вкусовщина. Мне наоборот - JSON привычнее.

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

Так вы не то читаете. Кавычки вложенные кто делать будет? Внутри 'three' должен быть валидный json, внутри которого должен быть валидный json и так до самого конца.


Вот он


{"three": "{\\"two\\": \\"{\\\\\\"one\\\\\\": \\\\\\"{\\\\\\\\\\\\\\"json\\\\\\\\\\\\\\": [\\\\\\\\\\\\\\"it\'s\\\\\\\\\\\\\\", \\\\\\\\\\\\\\"simple\\\\\\\\\\\\\\"]}\\\\\\"}\\"}"}

Если понадобилось такое — ты в жизни делаешь точно что-то не то. И тебя боги прокляли.

Четырежды вложенный json — да. Дважды вложенный yaml (т.е. yaml в content в параметрах модуля у Ансибла) — вполне нормально и постоянно.

Дважды вложенный yaml (т.е. yaml в content в параметрах модуля у Ансибла) — вполне нормально и постоянно.

нет, это не нормально :-)

Почему это не нормально? Если файл три строчки, то зачем мне городить template, рвать людям контекст чтения, когда простой content заменяет его с не меньшим успехом?


А ещё могут быть сниппеты yaml'а в переменных группы или инвентори (тоже yaml).


Вот живой пример из кода:


- name: Write provisioning yaml for dashboard
  become: true
  copy:
    content: |
      ---
      apiVersion: 1
      providers:
      -   disableDeletion: true
          folder: node-exporter
          folderUid: 0881a6...
          name: Node Exporter Full
          options:
              path: /etc/grafana/....
          orgId: 1
          type: file
    dest: /etc/grafana/...full.yaml

И что в нём такого странного?

например то, что в YAML более одного способа делать мультилайн и они точно так же ущербны, т.к. очень чувствительны к tab/spaces. Неудивительно, что в кубере для секретов придумали base64 (там свои тараканы с этим, но по крайней мере это однозначное представление — а не это вот все)...

Если вам трудно с мультилайном, вы всегда можете плейнтекстом в "".


На фоне того, как с мультилайном в json, простите…
напоминаю, любой ваш трюк в json является валидным yaml, т.е. в yaml-файле вы его использовать можете.

Я могу ошибаться, но я почему то твёрдо уверен, что эти многочисленные экранирования — это не JSON, а python-овская строка и нюансы экранирования в питоне. Да, могу ошибаться.

Потому что это не корректный YAML/JSON
image

А вот у меня на скрине — корректный (и JSON и YAML)
image


К слову, в исходном JAML внутри тоже не валидный JSON, а валидный JAML. То есть если вдруг (действительно!) это не ошибка, и сравнивается, кто лучше держит себя в себе — Yaml-in-Yaml или JSON-in-JSON, что уже странно, то это не совсем корректно.

К слову #2, если формат позволяет перепутать строку со структурой и саму структуру, то это не совсем не преимущество формата.

+1


This version is included in macOS for compatibility with legacy software. 
Future versions of macOS will not include Python 2.7. 
Instead, it is recommended that you transition to using 'python3' from within Terminal.

Python 2.7.16 (default, Dec 21 2020, 23:00:36) 
[GCC Apple LLVM 12.0.0 (clang-1200.0.30.4) [+internal-os, ptrauth-isa=sign+stri on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> 
>>> a = {"three": "{\\"two\\": \\"{\\\\\\"one\\\\\\": \\\\\\"{\\\\\\\\\\\\\\"json\\\\\\\\\\\\\\": [\\\\\\\\\\\\\\"it\'s\\\\\\\\\\\\\\", \\\\\\\\\\\\\\"simple\\\\\\\\\\\\\\"]}\\\\\\"}\\"}"}
  File "<stdin>", line 1
    a = {"three": "{\\"two\\": \\"{\\\\\\"one\\\\\\": \\\\\\"{\\\\\\\\\\\\\\"json\\\\\\\\\\\\\\": [\\\\\\\\\\\\\\"it\'s\\\\\\\\\\\\\\", \\\\\\\\\\\\\\"simple\\\\\\\\\\\\\\"]}\\\\\\"}\\"}"}
                         ^
SyntaxError: invalid syntax
>>> a = {"three" : "test"}
>>> print a
{'three': 'test'}
>>> a = {"three" : "{\"test\":\"olo\"}"}
>>> print a
{'three': '{"test":"olo"}'}

сами же в экранированиях и запутались как в трех соснах. А почему? Просто потому что не нужно так делать.

Именно это я и хотел показать — сравнение вложенности самовложенности yaml'а с самовложенностью json'а. С кавычками извините (ещё один привет json'у, кстати).

Про yaml ничего не скажу, но в противостоянии JSON и XML вообще не понимаю почему последнее время все на JSON помещались. И то и то без pretty форматирования не читабельны, зато с pretty форматированием XML намного читабельнее и проще для восприятия (на мой взгляд). JSON - это просто модный формат - ни больше ни меньше. Особенно вот эта канитель с запятой после последнего элемента (что её быть не должно) - источник ошибок. Мол если элемент последний, то запятая не нужна, если не последний - то нужна. Стандартная проблема: удалить последний элемент, забыть удалить запятую в конце предыдущего элемента и поломать файл.

Мне кажется, что формально pretty print xml-ей без изменения семантики невозможен,потому что вайтспейсы это текстовые ноды как любые другие.

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

Что лично меня всегда бесило в xml, так это отсутствие встроенных типов. То есть средний парсер не может догадаться где у меня число, а где строка. Я уже не говорю про нахождения списков когда они могут быть только с одним элементом.

Всё это решается или однозначной схемой данных замапленой на нативные объекты ЯП или системой типов поверх xml. Но второе делает ещё менее возможно читать/писать данные самому, а часто отдающая сторона просто этого не делает и хоть иди вешайся. Что касается первого, то оно с любым форматом не всегда возможно/имеет смысл.

То есть json тоже имеет проблемы с типами, просто с более сложными (как дата и время например), но в среднем это решается малой кровью.

P. S. ну а trailing commas нужно, конечно же, разрешить везде. Недостатков у них нет, а польза налицо

Вообще говоря если у вас люди пишут сложный xml без xsd или dtd они сами себе злобные буратины. Что еще веселее в json людям пришлось в итоге делать тоже самое :)
Да-да-да я про json schema

Да кто же про сложный говорит, хеловорлд на пять строчек пока напишешь уже устанешь.
Кстати, сам процесс написания xsd это отдельный род мазохизма :-)
Что лично меня всегда бесило в xml, так это отсутствие встроенных типов. То есть средний парсер не может догадаться где у меня число, а где строка. Я уже не говорю про нахождения списков когда они могут быть только с одним элементом.

а если мне нужны особые форматы данных? Ну, не просто float, а супер-пупер my_float со своей длиной? Или сериализация структуры данных, которая по сути превратится в бинарный блоб (vivat protobuf'ам)?

так же как в xml, городить свой огород поверх или парсить из строки.

просто json ближе к нативным структурам распространённых языков программирования (java, js, c/c++, python, go - you name it) так что в среднем по больнице боли от него меньше. а так и бинарные блобы бывает нужно по сети гонять и парсить строки вообще без структуры - json не супер инструмент, он просто обычно удобнее xml.

UPD: для передачи данных по сети в среднем удобнее, задачи бывают разные. например fb2 прекрасен не вопреки а благодаря xml.

Проблем у XML две: неоднозначность (для чтения/составления) и многословность (при обмене данных). Ну, и ещё большинство систем его обрабатывают медленнее, чем JSON.

<Товары>
	<Товар Цена="12">
		<Цена>13<Цена>
	</Товар>
	<Товар Цена="14">
		<Цена>15<Цена>
		<Цена>16<Цена>
	</Товар>
</Товар><!-- вот эта канитель с правильным закрытием тоже -->

Его название включает понятие markup (разметка), потому что в коде он включает дополнительные детали как форматировать текст, шрифт, его цвет и размер

Это про HTML, но не про XML

В некоторых особенно продвинутых (на мой взгляд) компаниях при устройстве на работу могут попросить представить рассказ о себе в виде JSON

А должность какая? Специалист по связям с машинами?

Оппозиционер XML это YAML, он не использует разметку (markup)

Тем не менее, YAML - «Yet Another Markup Language», а всё потому, что markup - это не про ту разметку из первой цитаты

Тем не менее


YAML (акроним англ. «Yet Another Markup Language» — «Ещё один язык разметки», позже — рекурсивный акроним англ. «YAML Ain't Markup Language» — «YAML — не язык разметки»)

Это не делает XML языком разметки в смысле форматирования текста

Насчет должности. Информация эта подчерпнута мной от Knox Hutchinson (https://www.youtube.com/channel/UCi7SD3zfCjkiDWvSFthIQSg). В 2013 году он устраивался на должность a junior software developer в городе Baton Rouge, Louisiana. На собеседовании одним из заданий было переписать его резюме в формате JSON и POST его на REST API.
import json
import requests
with open('cv') as f:
   requests.post('http://example.com/rest/cv', data=json.dumps(f.read()))

Если что, строчка в кавычках — это валидный json.

JSON, XML & co объединяет одно неприятное (в ряде случаев) свойство — они ужасно раздуты, потому что для передачи структурированных данных повторяют (в текстовом виде) описание каждой структуры снова и снова.


Почему их используют как формат сериализации при наличии Protocol Buffers и аналогичых форматов — загадка, ибо траффика они жрут просто немеряно, а если учесть затраты на парсинг и генерацию — то и процессорное время тоже (соответственно — энергию), существенно больше чем бинарные структурные форматы.


Да, для отладки и (может быть) разбора полётов удобно (и то в pretty виде) — но цена за это очень высока в планетарных масштабах.


Если же говорить про использование JSON для человекочитабельных применений… есть гораздо более приятные (лучше YAML) варианты типа HOCON, без всех этих извращений типа кавычек вокруг имен ключей (зачем они там вообще?).


Читать (глазами) конфигурации в JSON или XML, не говоря уже про писать — просто боль, если это больше чем два десятка строк, а если вспомнить что в JSON даже комментариев нет то становится совсем грустно.

Разбирать инопланетный xml приятнее, чем инопланетный блоб. Если когда-нибудь в WSUS заглядывали — это оно.

А инопланетный JSON - ещё приятнее, IMHO

Есть же читаталки для блобов, логи наконец. Но ради того чтобы удобно было разбираться (пока идёт отладка) — потом жертвовать траффиком и ресурсами? Может кровавому энтерпрайзу и пофиг на это, но есть ещё куча менее кровавых применений, где ресурсы не резиновые а процессоры не способны выполнять бесконечные циклы за 1 секунду.


Прокачка (с разбором) JSON объёмом в 10MB в разы медленней чем блоб такого же размера, не говоря уже что в блобе данные более компактны. Не зря ведь появились PB/CBOR/etc — потому что текстовые форматы очень избыточны и ресурсоёмки, даже HTTP/2 и HTTP/3 ушли в бинарный формат а не в JSON (и особо никто не страдает).

Прекрасный пример тут недавно был про GTA Online c JSON размером как раз 10 МБ.

И да и нет. Если у вас идёт 10к запросов в секунду, иметь 10М json'ы в процессе — непозволительная роскошь. Но весьма часто во-первых они не 10Мб в размере, во-вторых у вас один запрос в минуту (а то и просто "1 запрос").


На самом деле всё сводится к тому, что важнее — удобство или производительность. Например, у вас есть бинарная хранилка конфигов. Называется "реестр windows" и это одно из самых ужасных порождений инженерной мысли (бинарное блобохранилище без схемы). Сравните с (относительно) уютной помоечкой /etc в юниксах.


В то же самое время, слать ip-пакеты в json формате на инспекцию, когда к вам пришло 10Гбит флуда — так себе занятие.


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

Хочу знать, может тут поможете.

Вот значит у нас есть объект в объекте. Так как получить с помощью python именно внутренний объект как массив? Т. Е. Чтоб задавая ключь типо A[key] Я получал значение второго объекта находящегося в родительском первичном?

Я получал значение второго объекта находящегося в родительском первичном?

берешь и получаешь, никаких проблем.


[GCC Apple LLVM 12.0.0 (clang-1200.0.30.4) [+internal-os, ptrauth-isa=sign+stri on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> 
>>> a = ['a','b',{'lol':['blablabla']}]
>>> print a
['a', 'b', {'lol': ['blablabla']}]
>>> print a[2]
{'lol': ['blablabla']}
>>> print a[2]['lol']
['blablabla']
>>> 

и т.д.

Его название включает понятие markup (разметка), потому что в коде он включает дополнительные детали как форматировать текст, шрифт, его цвет и размер.


Дальше не читал.

Шикарно. В статье про JSON 3 разных вида кавычек:
пример — {“height”: “105m”, “color”: “red”}
Ес-но это работать не будет ;(((

Я запутался о чем тут...

по мнению автора, у читателя могут быть вопросы к описанным форматам, но абсолютно не возникает вопросов к пониманию следующего:

Я отправлю запрос на коммутатор CloudEngine6800 из playbook файла команду display int GE1/0/1:

Как же так-то...

Only those users with full accounts are able to leave comments. Log in, please.