json — Кодер и декодер JSON¶
JSON (Объектная нотация JavaScript), определяется RFC 7159 (заменяет устаревшее RFC 4627) и ECMA-404, является лёгким форматом обмена данными, вдохновленным JavaScript объектным литеральным синтаксисом (хотя он не является строгим подмножеством JavaScript [1]).
json предоставляет API, знакомый пользователям модулей стандартной библиотеки marshal и pickle .
Кодирование базовой иерархии объектов Python:
Специализируется на декодировании JSON объектов:
Использование json.tool из оболочки для проверки и красивой печати:
JSON — это подмножество YAML 1.2. JSON создан настройками этого модуля по умолчанию (в частности, значением по умолчанию разделителей), также является подмножеством YAML 1.0 и 1.1. Таким образом, данный модуль также можно использовать как YAML сериализатор.
Кодеры и декодеры этого модуля по умолчанию сохраняют порядок ввода и вывода. Порядок теряется только в том случае, если нижележащие контейнеры неупорядоченны.
До Python 3.7 порядок dict не гарантировался, поэтому входные и выходные данные обычно скремблировались, если collections.OrderedDict не запрашивался специально. Начиная с Python 3.7, обычный dict стал сохранять порядок, поэтому больше не нужно указывать collections.OrderedDict для генерации и парсинга JSON.
Основное использование¶
Сериализовать obj как поток в формате JSON в fp (поддерживающий .write() файлоподобный объект ), используя таблицы преобразования .
Если skipkeys истинно (по умолчанию: False ), то ключи dict, которые не относятся к базовому типу ( str , int , float , bool , None ), будут пропущены вместо вызова TypeError .
Модуль json всегда создаёт объекты str , а не объекты bytes . Следовательно, fp.write() должен поддерживать ввод str .
Если ensure_ascii истинно (по умолчанию), на выходе гарантированно будут экранированы все входящие не-ASCII символы. Если ensure_ascii ложно, эти символы будут выведены как есть.
Если у check_circular ложно значение (по умолчанию: True ), то проверка циклической ссылки для типов контейнеров будет пропущена, а циклическая ссылка приведёт к OverflowError (или хуже).
Если у allow_nan значение ложь (по умолчанию: True ), то это приведёт к ValueError для сериализации вне диапазона значений float ( nan , inf , -inf ) в строгом соответствии со спецификацией JSON. Если allow_nan истинно, будут использоваться их JavaScript эквиваленты ( NaN , Infinity , -Infinity ).
Если indent является неотрицательным целым числом или строкой, тогда элементы массива JSON и члены объекта будут приятно напечатаны с заданным уровнем отступа. Уровень отступа 0, отрицательный или «» вставляет только новые строки. None (по умолчанию) выбирает наиболее компактное представление. Использование положительного целочисленного отступа позволяет увеличить количество пробелов на уровне. Если indent — строка (например, «\t» ), строка используется для отступа на каждом уровне.
Изменено в версии 3.2: Разрешены строки для indent в дополнение к целым числам.
Если указано, separators должен быть кортежем (item_separator, key_separator) . По умолчанию используется (‘, ‘, ‘: ‘) , если indent — это None , и (‘,’, ‘: ‘) в противном случае. Чтобы получить наиболее компактное представление JSON, вы должны указать (‘,’, ‘:’) , чтобы исключить пробелы.
Изменено в версии 3.4: Использовать (‘,’, ‘: ‘) по умолчанию, если indent не None .
Если указано, default должна быть функцией, вызываемой для объектов, которые иначе не могут быть сериализованы. Он должен возвращать кодируемую JSON версию объекта или вызывать TypeError . Если не указано, вызывается TypeError .
Если sort_keys истинно (по умолчанию: False ), то вывод словарей будет отсортирован по ключу.
Чтобы использовать собственный подкласс JSONEncoder (например, тот, который переопределяет метод default() для сериализации дополнительных типов), укажите его с помощью cls kwarg; в противном случае используется JSONEncoder .
Изменено в версии 3.6: Все необязательные параметры теперь только ключевые .
В отличие от pickle и marshal , JSON не является протоколом с фреймами, поэтому попытка сериализации нескольких объектов с повторными вызовами dump() с использованием того же fp приведёт к получению недопустимого файла JSON.
Сериализовать obj в формате JSON str , используя таблицы преобразования . Аргументы имеют то же значение, что и в dump() .
Ключи в парах ключ/значение JSON всегда имеют тип str . Когда словарь преобразуется в JSON, все ключи словаря переводятся в строки. В результате, если словарь преобразуется в JSON, а затем обратно в словарь, словарь может не совпадать с исходным. Т. е. loads(dumps(x)) != x , если x имеет нестроковые ключи.
Десериализовать fp (поддерживающий .read() текстовый файл или двоичный файл , содержащий документ JSON) в объект Python, используя таблицу преобразования .
object_hook — это дополнительная функция, которая будет вызываться с результатом декодирования любого литерала объекта ( dict ). Возвращаемое значение object_hook будет использоваться вместо dict . Функция может использоваться для реализации пользовательских декодеров (например, хинтинг класса JSON-RPC).
object_pairs_hook — это дополнительная функция, которая будет вызываться с результатом декодирования любого литерала объекта с помощью упорядоченного списка пар. Возвращаемое значение object_pairs_hook будет использоваться вместо dict . Эту функцию можно использовать для реализации настраиваемых декодеров. Если также определен object_hook, приоритет имеет object_pairs_hook.
Изменено в версии 3.1: Добавлена поддержка object_pairs_hook.
parse_float, если он указан, будет вызываться со строкой каждого декодируемого числа с плавающей запятой JSON. По умолчанию это эквивалент float(num_str) . Это можно использовать для использования другого типа данных или парсера для чисел с плавающей запятой JSON (например, decimal.Decimal ).
parse_int, если он указан, будет вызываться со строкой каждого типа JSON int, подлежащего декодированию. По умолчанию это эквивалент int(num_str) . Это можно использовать для использования другого типа данных или парсера для целых чисел JSON (например, float ).
parse_constant, если он указан, будет вызываться с одной из следующих строк: ‘-Infinity’ , ‘Infinity’ , ‘NaN’ . Это можно использовать для вызова исключения, если встречаются недопустимые числа JSON.
Изменено в версии 3.1: parse_constant больше не вызывается для значений «null», «true», «false».
Чтобы использовать собственный подкласс JSONDecoder , укажите его с помощью cls kwarg; в противном случае используется JSONDecoder . Дополнительные ключевые аргументы будут переданы конструктору класса.
Если десериализуемые данные не являются допустимым документом JSON, будет выдан JSONDecodeError .
Изменено в версии 3.6: Все необязательные параметры теперь только ключевые .
Изменено в версии 3.6: fp теперь может быть двоичным файлом . Кодировка ввода должна быть UTF-8, UTF-16 или UTF-32.
Десериализовать s (экземпляр str , bytes или bytearray , содержащий документ JSON) в объект Python, используя таблицу преобразования .
Остальные аргументы имеют то же значение, что и в load() , за исключением encoding, который игнорируется и считается устаревшим, начиная с Python 3.1.
Если десериализуемые данные не являются допустимым документом JSON, будет вызвано JSONDecodeError .
Устарело с версии 3.1, будет удалено в 3.9 версии.: encoding ключевой аргумент.
Изменено в версии 3.6: s теперь может быть типа bytes или bytearray . Кодировка ввода должна быть UTF-8, UTF-16 или UTF-32.
Кодеры и декодеры¶
Простой декодер JSON.
По умолчанию выполняет следующие переводы при декодировании:
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number (int) | int |
number (real) | float |
true | True |
false | False |
null | None |
Он также понимает NaN , Infinity и -Infinity как соответствующие им значения float , что выходит за рамки спецификации JSON.
object_hook, если он указан, будет вызываться с результатом каждого декодированного объекта JSON, и его возвращаемое значение будет использоваться вместо данного dict . Это можно использовать для предоставления настраиваемых десериализаций (например, для поддержки подсказок классов JSON-RPC).
object_pairs_hook, если указано, будет вызываться с результатом декодирования каждого объекта JSON с помощью упорядоченного списка пар. Возвращаемое значение object_pairs_hook будет использоваться вместо dict . Эту функцию можно использовать для реализации настраиваемых декодеров. Если также определён object_hook, приоритет имеет object_pairs_hook.
Изменено в версии 3.1: Добавлена поддержка object_pairs_hook.
parse_float, если он указан, будет вызываться со строкой каждого декодируемого числа с плавающей запятой JSON. По умолчанию это эквивалент float(num_str) . Это можно использовать для использования другого типа данных или парсера для чисел с плавающей запятой JSON (например, decimal.Decimal ).
parse_int, если он указан, будет вызываться со строкой каждого типа JSON int, подлежащего декодированию. По умолчанию это эквивалент int(num_str) . Это можно использовать для использования другого типа данных или парсера для целых чисел JSON (например, float ).
parse_constant, если он указан, будет вызываться с одной из следующих строк: ‘-Infinity’ , ‘Infinity’ , ‘NaN’ . Это можно использовать для вызова исключения, если встречаются недопустимые числа JSON.
Если strict имеет значение ложь ( True по умолчанию), то внутри строк будут разрешены управляющие символы. Управляющими символами в этом контексте являются символы с кодами символов в диапазоне от 0 до 31, включая ‘\t’ (табуляция), ‘\n’ , ‘\r’ и ‘\0’ .
Если десериализуемые данные не являются допустимым документом JSON, будет вызвано JSONDecodeError .
Изменено в версии 3.6: Все параметры теперь только ключевые .
Возвращает представление Python s (экземпляр str , содержащий документ JSON).
JSONDecodeError будет вызван, если данный документ JSON недействителен.
Расшифровать документ JSON из s ( str , начинающийся с документа JSON) и возвращает кортеж из двух представлений Python и индекс в s, где заканчивается документ.
Это можно использовать для декодирования документа JSON из строки, в конце которой могут быть посторонние данные.
class json. JSONEncoder ( *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None ) ¶
Расширяемый кодировщик JSON для структур данных Python.
По умолчанию поддерживает следующие объекты и типы:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int- & float-derived Enums | number |
True | true |
False | false |
None | null |
Изменено в версии 3.4: Добавлена поддержка классов Enum, производных от int и float.
Чтобы расширить это для распознавания других объектов, создайте подкласс и реализуйте метод default() с другим методом, который возвращает сериализуемый объект для o , если это возможно, в противном случае он должен вызвать реализацию суперкласса (чтобы вызвать TypeError ).
Если skipkeys ложно (по умолчанию), то это TypeError для попытки кодирования ключей, которые не являются str , int , float или None . Если skipkeys истинно, такие элементы просто пропускаются.
Если ensure_ascii истинно (по умолчанию), на выходе гарантированно будут экранированы все входящие не-ASCII символы. Если ensure_ascii ложно, эти символы будут выведены как есть.
Если check_circular истинно (по умолчанию), то списки, словари и объекты пользовательского кодирования будут проверяться на предмет циклических ссылок во время кодирования, чтобы предотвратить бесконечную рекурсию (которая может вызвать OverflowError ). В противном случае такая проверка не проводится.
Если allow_nan истинно (по умолчанию), то NaN , Infinity и -Infinity будут закодированы как таковые. Такое поведение не соответствует спецификации JSON, но согласуется с большинством кодеров и декодеров на основе JavaScript. В противном случае это будет ValueError для кодирования таких чисел с плавающей запятой.
Если sort_keys истинно (по умолчанию: False ), то вывод словарей будет отсортирован по ключу; это полезно для регрессионных тестов, чтобы гарантировать ежедневное сравнение сериализаций JSON.
Если indent является неотрицательным целым числом или строкой, тогда элементы массива JSON и члены объекта будут приятно напечатаны с этим уровнем отступа. Уровень отступа 0, отрицательный или «» вставляет только новые строки. None (по умолчанию) выбирает наиболее компактное представление. Использование положительного целочисленного отступа позволяет увеличить количество пробелов на уровне. Если indent — строка (например, «\t» ), строка используется для отступа на каждом уровне.
Изменено в версии 3.2: Разрешить строки для indent в дополнение к целым числам.
Если указано, separators должен быть кортежем (item_separator, key_separator) . По умолчанию используется (‘, ‘, ‘: ‘) , если indent — None , и (‘,’, ‘: ‘) в противном случае. Чтобы получить наиболее компактное представление JSON, вы должны указать (‘,’, ‘:’) , чтобы исключить пробелы.
Изменено в версии 3.4: Использовать (‘,’, ‘: ‘) по умолчанию, если indent не None .
Если указано, default должна быть функцией, вызываемой для объектов, которые иначе не могут быть сериализованы. Он должен возвращать кодируемую JSON версию объекта или вызывать TypeError . Если не указано, вызывается TypeError .
Изменено в версии 3.6: Все параметры теперь только ключевые .
Реализуйте этот метод в подклассе, чтобы он возвращал сериализуемый объект для o или вызывал базовую реализацию (чтобы вызвать TypeError ).
Например, для поддержки произвольных итераторов вы можете реализовать по умолчанию вот так:
Возвращает строковое представление JSON структуры данных Python, o. Например:
Закодировать данный объект o и отдать каждое строковое представление как доступное. Например:
Исключения¶
Подкласс ValueError со следующими дополнительными атрибутами:
Неформатированное сообщение об ошибке.
Анализируемый JSON документ.
Начальный индекс doc, парсинг которого не удался.
Строка, соответствующая pos.
Столбец, соответствующий pos.
Добавлено в версии 3.5.
Соответствие стандартам и совместимость¶
Формат JSON определяется RFC 7159 и ECMA-404. В этом разделе подробно описан уровень соответствия этого модуля RFC. Для простоты подклассы JSONEncoder и JSONDecoder и другие параметры, кроме явно указанных, не рассматриваются.
Этот модуль не соответствует стандарту RFC в строгом соответствии с реализацией некоторых расширений, которые являются допустимым JavaScript, но не допустимым JSON. Особенно:
- Принимаются и выводятся бесконечные числовые значения и числа NaN;
- Допускаются повторяющиеся имена внутри объекта, и используется только значение последней пары имя-значение.
Поскольку RFC разрешает RFC-совместимым парсерам принимать входные тексты, которые не являются RFC-совместимыми, десериализатор этого модуля технически совместим с RFC при настройках по умолчанию.
Кодировки символов¶
RFC требует, чтобы JSON был представлен с использованием UTF-8, UTF-16 или UTF-32, при этом UTF-8 является рекомендуемым по умолчанию для максимальной совместимости.
Как разрешено, хотя и не требуется, RFC, сериализатор модуля устанавливает ensure_ascii=True по умолчанию, таким образом экранируя вывод, так что результирующие строки содержат только символы ASCII.
За исключением параметра ensure_ascii, модуль определяется строго с точки зрения преобразования между объектами Python и Unicode strings , и, таким образом, напрямую не решает проблему кодировок символов.
RFC запрещает добавлять метку порядка байтов (BOM) в начало JSON текста, и сериализатор модуля не добавляет BOM к своему выходу. RFC разрешает, но не требует, чтобы десериализаторы JSON игнорировали исходную спецификацию во входных данных. Десериализатор модуля вызывает ValueError , когда присутствует начальный BOM.
RFC явно не запрещает содержащие последовательности байтов JSON строки, которые не соответствуют допустимым символам Юникода (например, непарные суррогаты UTF-16), но отмечает, что они могут вызвать проблемы совместимости. По умолчанию данный модуль принимает и выводит (если присутствует в исходном str ) кодовые точки для таких последовательностей.
Бесконечные и NaN числовые значения¶
RFC не разрешает представление бесконечных числовых значений или NaN значений. Несмотря на это, по умолчанию этот модуль принимает и выводит Infinity , -Infinity и NaN , как если бы они были действительными числовыми литералами JSON:
В сериализаторе можно использовать параметр allow_nan, чтобы изменить это поведение. В десериализаторе для изменения этого поведения можно использовать параметр parse_constant.
Повторяющиеся имена внутри объекта¶
RFC указывает, что имена в объекте JSON должны быть уникальными, но не определяет, как следует обрабатывать повторяющиеся имена в объектах JSON. По умолчанию этот модуль не вызывает исключения; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
Параметр object_pairs_hook можно использовать для изменения этого поведения.
Необъектные значения верхнего уровня, не являющиеся массивами¶
Старая версия JSON, указанная устаревшим RFC 4627, требовала, чтобы значение верхнего уровня текста JSON было либо объектом JSON, либо массивом (Python dict или list ) и не могло быть пустым JSON, логическим, числом или строковым значением. RFC 7159 снял это ограничение, и этот модуль не применяет и никогда не реализовывал это ограничение ни в сериализаторе, ни в десериализаторе.
Тем не менее, для максимальной совместимости вы можете добровольно соблюдать ограничение самостоятельно.
Ограничения реализации¶
Некоторые реализации десериализатора JSON могут устанавливать ограничения на:
- размер принимаемых текстов JSON
- максимальный уровень вложенности объектов и массивов JSON
- диапазон и точность чисел JSON
- содержимое и максимальная длину строк JSON
Этот модуль не налагает каких-либо таких ограничений, кроме ограничений самих соответствующих типов данных Python или самого интерпретатора Python.
При сериализации в JSON остерегайтесь любых таких ограничений в приложениях, которые могут использовать ваш JSON. В частности, числа JSON обычно десериализуются в числа с двойной точностью IEEE 754 и, таким образом, подчиняются ограничениям диапазона и точности этого представления. Это особенно актуально при сериализации значений Python int чрезвычайно большой величины или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal .
Интерфейс командной строки¶
Модуль json.tool предоставляет простой интерфейс командной строки для проверки и приятной печати JSON объектов.
Если необязательные аргументы infile и outfile не указаны, будут использоваться sys.stdin и sys.stdout соответственно:
Изменено в версии 3.5: Теперь вывод находится в том же порядке, что и ввод. Использовать опцию —sort-keys для сортировки вывода словарей в алфавитном порядке по ключам.
Python Encode Unicode and non-ASCII characters as-is into JSON
In this article, we will address the following frequently asked questions about working with Unicode JSON data in Python.
- How to serialize Unicode or non-ASCII data into JSON as-is strings instead of \u escape sequence (Example, Store Unicode string ø as-is instead of \u00f8 in JSON)
- Encode Unicode data in utf-8 format.
- How to serialize all incoming non-ASCII characters escaped (Example, Store Unicode string ø as \u00f8 in JSON)
Further Reading:
- Solve Python JSON Exercise to practice Python JSON skills
The Python RFC 7159 requires that JSON be represented using either UTF-8, UTF-16, or UTF-32, with UTF-8 being the recommended default for maximum interoperability.
The ensure_ascii parameter
Use Python’s built-in module json provides the json.dump() and json.dumps() method to encode Python objects into JSON data.
The json.dump() and json.dumps() has a ensure_ascii parameter. The ensure_ascii is by-default true so the output is guaranteed to have all incoming non-ASCII characters escaped. If ensure_ascii=False , these characters will be output as-is.
The json module always produces str objects. You get a string back, not a Unicode string. Because the escaping is allowed by JSON.
- using a ensure_ascii=True , we can present a safe way of representing Unicode characters. By setting it to true we make sure the resulting JSON is valid ASCII characters (even if they have Unicode inside).
- Using a ensure_ascii=False , we make sure resulting JSON store Unicode characters as-is instead of \u escape sequence.
Save non-ASCII or Unicode data as-is not as \u escape sequence in JSON
In this example, we will try to encode the Unicode Data into JSON. This solution is useful when you want to dump Unicode characters as characters instead of escape sequences.
Set ensure_ascii=False in json.dumps() to encode Unicode as-is into JSON
Output:
Note: This example is useful to store the Unicode string as-is in JSON.
JSON Serialize Unicode Data and Write it into a file.
In the above example, we saw how to Save non-ASCII or Unicode data as-is not as \u escape sequence in JSON. Now, Let’s see how to write JSON serialized Unicode data as-is into a file.
Output:
JSON file after writing Unicode data as-is
Serialize Unicode objects into UTF-8 JSON strings instead of \u escape sequence
You can also set JSON encoding to UTF-8. UTF-8 is the recommended default for maximum interoperability. set ensure_ascii=False to and encode Unicode data into JSON using ‘UTF-8‘.
Output:
Encode both Unicode and ASCII (Mix Data) into JSON using Python
In this example, we will see how to encode Python dictionary into JSON which contains both Unicode and ASCII data.
Output:
Python Escape non-ASCII characters while encoding it into JSON
Let’ see how store all incoming non-ASCII characters escaped in JSON. It is a safe way of representing Unicode characters. By setting ensure_ascii=True we make sure resulting JSON is valid ASCII characters (even if they have Unicode inside).
Output:
Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.
About Vishal
Founder of PYnative.com I am a Python developer and I love to write articles to help developers. Follow me on Twitter. All the best for your future Python endeavors!
Related Tutorial Topics:
Python Exercises and Quizzes
Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.
Как записать в json кириллицу python
This article will provide a comprehensive guide on how to work with Unicode and non-ASCII characters in Python when generating and parsing JSON data. We will look at the different ways to handle Unicode and non-ASCII characters in JSON. By the end of this article, you should have a good understanding of how to work with Unicode and non-ASCII characters in JSON using Python. Also, we are going to cover the following topics related to encoding and serializing Unicode and non-ASCII characters in Python:
- How to encode Unicode and non-ASCII characters into JSON in Python.
- How to save non-ASCII or Unicode data as-is, without converting it to a \u escape sequence, in JSON.
- How to serialize Unicode data and write it into a file.
- How to serialize Unicode objects into UTF-8 JSON strings, instead of \u escape sequences.
- How to escape non-ASCII characters while encoding them into JSON in Python.
What is a UTF-8 Character?
Unicode is a standardized encoding system that represents most of the world’s written languages. It includes characters from many different scripts, such as Latin, Greek, and Chinese, and is capable of representing a wide range of characters and symbols. Non-ASCII characters are characters that are not part of the ASCII (American Standard Code for Information Interchange) character set, which consists of only 128 characters.
UTF-8 is a character encoding that represents each Unicode code point using one to four bytes. It is the most widely used character encoding for the Web and is supported by all modern web browsers and most other applications. UTF-8 is also backward-compatible with ASCII, so any ASCII text is also a valid UTF-8 text.
Сохранение текстов utf-8 в json.dumps как UTF8, а не как escape-последовательность
Есть ли способ сериализации объектов в строку JSON UTF-8 (вместо\uXXXX)?
это работает, но если какой-либо подобъект является Python-Unicode, а не UTF-8, он будет выводить мусор:
9 ответов
Используйте переключатель ensure_ascii=False в json.dumps() , затем вручную закодируйте значение в UTF-8:
Если вы пишете это в файл, вы можете использовать io.open() вместо open() для создания файлового объекта, который кодирует значения Unicode для вас, поскольку вы напишите, затем используйте json.dump() вместо этого, чтобы записать в этот файл:
В Python 3 встроенный open() является псевдонимом для io.open() . Обратите внимание на наличие ошибки в модуле json , где флаг ensure_ascii=False может создавать комбинации объектов unicode и str . Обходной путь для Python 2:
Если вы передаете байтовые строки (введите str в Python 2, bytes в Python 3), закодированные в UTF-8, обязательно установите ключевое слово encoding :
Обратите внимание, что ваш второй образец не действителен Unicode; вы дали ему байты UTF-8 как литерал в Юникоде, который никогда не работал бы:
Только когда я закодировал эту строку на латиницу 1 (чьи юникодовые кодовые точки сопоставляют друг с другом по байтам), затем декодируем как UTF-8, вы видите ожидаемый вывод. Это не имеет ничего общего с JSON и все, что связано с тем, что вы используете неправильный ввод. Результат называется Mojibake.
Если вы получили это значение Unicode из строкового литерала, оно было декодировано с использованием неправильного кодека. Возможно, ваш терминал неправильно настроен или ваш текстовый редактор сохранил исходный код с помощью другого кодека, чем то, что вы сказали Python для чтения файла. Или вы получили его из библиотеки, которая применяла неправильный кодек. Все это не имеет ничего общего с библиотекой JSON.