Функция load() модуля json в python

Содержание:

Пример схемы JSON

Ниже приведена базовая схема JSON, которая охватывает классическое описание каталога продукции —

{
   "$schema": "http://json-schema.org/draft-04/schema#",
   "title": "Product",
   "description": "A product from Acme's catalog",
   "type": "object",
	
   "properties": {
	
      "id": {
         "description": "The unique identifier for a product",
         "type": "integer"
      },
		
      "name": {
         "description": "Name of the product",
         "type": "string"
      },
		
      "price": {
         "type": "number",
         "minimum": 0,
         "exclusiveMinimum": true
      }
   },
	
   "required": 
}

Давайте проверим различные важные ключевые слова, которые можно использовать в этой схеме —

Sr.No. Ключевое слово и описание
1

$ схема

Ключевое слово $ schema указывает, что эта схема написана согласно черновой спецификации v4.

2

заглавие

Вы будете использовать это, чтобы дать название вашей схеме.

3

описание

Небольшое описание схемы.

4

тип

Ключевое слово type определяет первое ограничение для наших данных JSON: это должен быть объект JSON.

5

свойства

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

6

требуется

Это хранит список обязательных свойств.

7

минимальный

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

8

exclusiveMinimum

Если присутствует «exclusiveMinimum» и имеет логическое значение true, экземпляр действителен, если он строго больше значения «минимума».

9

максимальная

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

10

exclusiveMaximum

Если присутствует «exclusiveMaximum» и имеет логическое значение true, экземпляр действителен, если он строго ниже значения «Maximum».

11

multipleOf

Числовой экземпляр действителен для «множественного значения», если результатом деления экземпляра по значению этого ключевого слова является целое число.

12

максимальная длина

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

13

MINLENGTH

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

14

шаблон

Экземпляр строки считается допустимым, если регулярное выражение соответствует экземпляру успешно.

Вы можете проверить http://json-schema.org для полного списка ключевых слов, которые можно использовать при определении схемы JSON. Приведенную выше схему можно использовать для проверки правильности следующего кода JSON:

JSON — Сравнение с XML

JSON и XML являются удобочитаемыми форматами и не зависят от языка. Они оба поддерживают создание, чтение и декодирование в реальных ситуациях. Мы можем сравнить JSON с XML, основываясь на следующих факторах:

Complex Object encoding of Python

A Complex object has two different parts that is

  1. Real part
  2. Imaginary part

Example: 3 +2i

Before performing encoding of a complex object, you need to check a variable is complex or not. You need to create a function which checks the value stored in a variable by using an instance method.

Let’s create the specific function for check object is complex or eligible for encoding.

import json

# create function to check instance is complex or not
def complex_encode(object):
    # check using isinstance method
    if isinstance(object, complex):
        return 
    # raised error using exception handling if object is not complex
    raise TypeError(repr(object) + " is not JSON serialized")


# perform json encoding by passing parameter
complex_obj = json.dumps(4 + 5j, default=complex_encode)
print(complex_obj)

Output:

''

numpy scalars¶

It’s not possible (without a lot of hacks) to encode numpy scalars. This is the case because some numpy scalars (float64, and depending on Python version also int64) are subclasses of float and int. This means that the Python json encoder will stringify them without them ever reaching the custom encoders.

So if you really want to encode numpy scalars, you’ll have to do the conversion beforehand. For that purpose you can use encode_scalars_inplace, which mutates a nested data structure (in place!) to replace any numpy scalars by their representation. If you serialize this result, it can subsequently be loaded without further adaptations.

It’s not great, but unless the Python json module changes, it’s the best that can be done. See issue 18 for more details.

(obj)

Searches a data structure of lists, tuples and dicts for numpy scalars
and replaces them by their dictionary representation, which can be loaded
by json-tricks. This happens in-place (the object is changed, use a copy).

Command Line Interface¶

Source code: Lib/json/tool.py

The module provides a simple command line interface to validate
and pretty-print JSON objects.

If the optional and arguments are not
specified, and will be used respectively:

$ echo '{"json": "obj"}' | python -m json.tool
{
    "json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Changed in version 3.5: The output is now in the same order as the input. Use the
option to sort the output of dictionaries
alphabetically by key.

Command line options

The JSON file to be validated or pretty-printed:

$ python -m json.tool mp_films.json

    {
        "title": "And Now for Something Completely Different",
        "year": 1971
    },
    {
        "title": "Monty Python and the Holy Grail",
        "year": 1975
    }

If infile is not specified, read from .

Write the output of the infile to the given outfile. Otherwise, write it
to .

Sort the output of dictionaries alphabetically by key.

New in version 3.5.

Disable escaping of non-ascii characters, see for more information.

New in version 3.9.

Parse every input line as separate JSON object.

New in version 3.8.

Mutually exclusive options for whitespace control.

New in version 3.9.

Show the help message.

Footnotes

As noted in the errata for RFC 7159,
JSON permits literal U+2028 (LINE SEPARATOR) and
U+2029 (PARAGRAPH SEPARATOR) characters in strings, whereas JavaScript
(as of ECMAScript Edition 5.1) does not.

19.2.2. Encoders and Decoders¶

class (*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)

Simple JSON decoder.

Performs the following translations in decoding by default:

JSON

Python

object

dict

array

list

string

str

number (int)

int

number (real)

float

true

True

false

False

null

None

It also understands , , and as their
corresponding values, which is outside the JSON spec.

object_hook, if specified, will be called with the result of every JSON
object decoded and its return value will be used in place of the given
. This can be used to provide custom deserializations (e.g. to
support JSON-RPC class hinting).

object_pairs_hook, if specified will be called with the result of every
JSON object decoded with an ordered list of pairs. The return value of
object_pairs_hook will be used instead of the . This
feature can be used to implement custom decoders that rely on the order
that the key and value pairs are decoded (for example,
will remember the order of insertion). If
object_hook is also defined, the object_pairs_hook takes priority.

Changed in version 3.1: Added support for object_pairs_hook.

parse_float, if specified, will be called with the string of every JSON
float to be decoded. By default, this is equivalent to .
This can be used to use another datatype or parser for JSON floats
(e.g. ).

parse_int, if specified, will be called with the string of every JSON int
to be decoded. By default, this is equivalent to . This can
be used to use another datatype or parser for JSON integers
(e.g. ).

parse_constant, if specified, will be called with one of the following
strings: , , .
This can be used to raise an exception if invalid JSON numbers
are encountered.

If strict is false ( is the default), then control characters
will be allowed inside strings. Control characters in this context are
those with character codes in the 0–31 range, including (tab),
, and .

If the data being deserialized is not a valid JSON document, a
will be raised.

Changed in version 3.6: All parameters are now .

(s)

Return the Python representation of s (a instance
containing a JSON document).

will be raised if the given JSON document is not
valid.

(s)

Decode a JSON document from s (a beginning with a
JSON document) and return a 2-tuple of the Python representation
and the index in s where the document ended.

This can be used to decode a JSON document from a string that may have
extraneous data at the end.

Сохранение данных в JSON

Чтобы записать информацию в формате JSON с помощью средств языка Python, нужно прежде всего подключить модуль json, воспользовавшись командой import json в начале файла с кодом программы. Метод dumps отвечает за автоматическую упаковку данных в JSON, принимая при этом переменную, которая содержит всю необходимую информацию. В следующем примере демонстрируется кодирование словаря под названием dictData. В нем имеются некие сведения о пользователе интернет-портала, такие как идентификационный код, логин, пароль, полное имя, номер телефона, адрес электронной почты и данные об активности. Эти значения представлены в виде обычных строк, а также целых чисел и булевых литералов True/False.

import json
dictData = { "ID"       : 210450,
             "login"    : "admin",
             "name"     : "John Smith",
             "password" : "root",
             "phone"    : 5550505,
             "email"    : "smith@mail.com",
             "online"   : True }
jsonData = json.dumps(dictData)
print(jsonData)

{"ID": 210450, "login": "admin", "name": "John Smith", "password": "root", "phone": 5550505, "email": "smith@mail.com", "online": true}

Результат выполнения метода dumps передается в переменную под названием jsonData. Таким образом, словарь dictData был преобразован в JSON-формат всего одной строчкой. Как можно увидеть, благодаря функции print, все сведения были закодированы в своем изначальном виде. Стоит заметить, что данные из поля online были преобразованы из литерала True в true.

С помощью Python сделаем запись json в файл. Для этого дополним код предыдущего примера следующим образом:

with open("data.json", "w") as file:
    file.write(jsonData)

Подробнее про запись данных в текстовые файлы описано в отдельной статье на нашем сайте.

All done!

Congratulations, you can now wield the mighty power of JSON for any and all of your nefarious Python needs.

While the examples you’ve worked with here are certainly contrived and overly simplistic, they illustrate a workflow you can apply to more general tasks:

  1. Import the package.
  2. Read the data with or .
  3. Process the data.
  4. Write the altered data with or .

What you do with your data once it’s been loaded into memory will depend on your use case. Generally, your goal will be gathering data from a source, extracting useful information, and passing that information along or keeping a record of it.

Today you took a journey: you captured and tamed some wild JSON, and you made it back in time for supper! As an added bonus, learning the package will make learning and a snap.

Создайте свой собственный кодер JSON

Модуль использует кодер под названием , который использует правила в приведенной выше таблице для кодирования объектов Python.

Однако он не кодирует все объекты Python, и в зависимости от проблемы, с которой мы сталкиваемся, нам может потребоваться написать наш собственный кодер JSON, чтобы кодировать эти объекты особым образом.

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

Для этой демонстрации мы возьмем массивы numpy и преобразуем их в объекты Python JSON. Теперь модуль json по умолчанию не может обрабатывать массивы numpy, поэтому, если вы попытаетесь преобразовать массив numpy без нашего расширенного класса, вы получите ошибку типа:

TypeError: Object of type ndarray is not JSON serializable

Давайте напишем этот класс для сериализации и кодирования массива numpy в объекты json, а также путем преобразования его в список Python в нашем методе handler.

import json
import numpy as np

class MyEncoder(json.JSONEncoder):
    # Handles the default behavior of
    # the encoder when it parses an object 'obj'
    def default(self, obj):
        # If the object is a numpy array
        if isinstance(obj, np.ndarray):
            # Convert to Python List
            return obj.tolist()
        else:
            # Let the base class Encoder handle the object
            return json.JSONEncoder.default(self, obj)


# Numpy array of floats
a = np.arange(1, 10, 0.5)
print(type(a), a)

# Pass our encoder to json.dumps()
b = json.dumps(a, cls=MyEncoder)
print(b)

Наконец, мы кодируем его, передавая имя класса параметру |/json.dumps()

Таким образом, вызов кодирования будет:

json_object = json.dumps(python_object, cls=MyEncoder)

Выход

Действительно, наш пользовательский кодер теперь может преобразовывать массивы numpy в объекты JSON! Сейчас мы завершили наш первый комплексный кодер.

Вы можете расширить эту функциональность, чтобы написать различные кодеры для вашего конкретного случая использования!

JSON-Encoder.

Синтаксис:

import json

json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, 
              check_circular=True, allow_nan=True, 
              sort_keys=False, indent=None, 
              separators=None, default=None)

Параметры:

  • — игнорирование не базовых типов ключей в словарях,
  • — экранирование не-ASSCI символов,
  • — проверка циклических ссылок,
  • — представление значений , , в JSON,
  • — сортировка словарей,
  • — количество отступов при сериализации,
  • — разделители используемые в JSON,
  • — метод подкласса для объектов, которые не могут быть сериализованы,

Описание:

Функция модуля расширяет возможности преобразование структур данных Python в формат JSON.

Поддерживает следующие объекты и типы по умолчанию:

Python JSON

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

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

Если аргумент имеет значение (по умолчанию), на выходе гарантированно все входящие не ASCII символы будут экранированы последовательностями \uXXXX. Если имеет значение , то не ASCII символы будут выводиться как есть.

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

Если аргумент (по умолчанию: ), при каждой попытке сериализировать значение , выходящее за допустимые пределы (, , ), будет возникать исключение , в соответствии с сертификацией JSON. В случае если , будут использованы JavaScript аналоги (, , ).

Если аргумент (по умолчанию: False), выводимый словарь будет отсортирован по именам ключей, что полезно для регрессивного тестирования.

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

Если указан аргумент , то он должен быть кортежем типа . По умолчанию используется если . Для получения наиболее компактного представления JSON следует использовать , чтобы уменьшить количество пробелов.

Значение должно быть методом подкласса . Он вызывается для объектов, которые не могут быть сериализованы. Метод должен вернуть кодируемую версию объекта JSON или вызывать исключение . Если аргумент не указан и какой-то из объектов не может быть преобразован в JSON, то возникает ошибка .

Методы класса .

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

Например, чтобы поддерживать произвольные итераторы, вы можете реализовать метод следующим образом:

def default(self, obj):
   try
       iterable = iter(obj)
   except TypeError
       pass
   else
       return list(iterable)
   # базовый класс вызывает исключение TypeError
   return json.JSONEncoder.default(self, obj)

Возвращает строковое представление JSON структуры данных Python.

json.JSONEncoder().encode({"foo" \"bar", "baz"\]})
'{"foo": \}'

Преобразовывает переданный объект o и выдаёт каждое строковое представление, как только оно становится доступным. Например:

for chunk in json.JSONEncoder().iterencode(bigobject):
    mysocket.write(chunk)

Примеры использования:

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return obj.real, obj.imag
...         # Let the base class default method raise the TypeError
...         return json.JSONEncoder.default(self, obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
# ''
>>> ComplexEncoder().encode(2 + 1j)
# ''
>>> list(ComplexEncoder().iterencode(2 + 1j))
# ']

Comments¶

This package uses and for comments, which seem to be the most common conventions, though only the latter is valid javascript.

For example, you could call on the following string:

{ # "comment 1
        "hello" "Wor#d", "Bye" "\"M#rk\"", "yes\\\"" 5,# comment" 2
        "quote" "\"th#t's\" what she said", // comment "3"
        "list" 1, 1, "#", "\"", "\\", 8], "dict" {"q" 7} #" comment 4 with quotes
}
// comment 5

And it would return the de-commented version:

{
        "hello" "Wor#d", "Bye" "\"M#rk\"", "yes\\\"" 5,
        "quote" "\"th#t's\" what she said",
        "list" 1, 1, "#", "\"", "\\", 8], "dict" {"q" 7}
}

Since comments aren’t stored in the Python representation of the data, loading and then saving a json file will remove the comments (it also likely changes the indentation).

JSON-декодер.

Синтаксис:

import json

class json.JSONDecoder(*, object_hook=None, parse_float=None, 
                        parse_int=None, parse_constant=None, 
                        strict=True, object_pairs_hook=None)

Параметры:

  • — пользовательская функция для преобразования каждого литерала словаря,
  • — пользовательская функция для преобразования литералов, похожих на ,
  • — пользовательская функция для преобразования литералов, похожих на ,
  • — пользовательская функция для преобразования литералов , и ,
  • — разрешить/запретить использование управляющих символов,
  • — пользовательская функция для преобразования литералов, , декодированных упорядоченным списком пар,

Описание:

Класс модуля представляет из себя простой JSON-декодер.

При десериализации выполняет следующие преобразования:

JSON Python

Класс также понимает , , и как соответствующие значения типа, которые находятся за пределами спецификации JSON.

Аргумент представляет собой пользовательскую функцию и если указана, то будет вызываться с результатом декодирования каждого объекта JSON , а ее возвращаемое значение будет использоваться вместо соответствующего словаря . Это поведение можно использовать для обеспечения настраиваемой десериализации.

Аргумент пользовательская функция и если указана, то будет вызываться с результатом каждого объекта JSON, декодированного упорядоченным списком пар. Возвращаемое значение будет использоваться вместо словаря . Эта функция может быть использована для реализации пользовательских декодеров. Если также определен, то имеет приоритет.

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

Аргумент — функция и если указана, будет вызываться для строки JSON с целым значением . По умолчанию, эквивалентно . Можно использовать для преобразования к другому типу данных, например .

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

Если аргумент ( по умолчанию), тогда использование управляющих символов внутри строк будет разрешено. В данном контексте управляющие символы — это символы с кодами в диапазоне 0–31, включая — tab, , и .

Если десериализованные данные не являются допустимым форматом JSON, будет вызвана ошибка .

Методы класса :

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

Метод декодирует JSON-документ из строки в формате JSON и возвращает двойной кортеж представление данной строки в Python и индекс в строки , где документ закончился.

Метод может быть использован для декодирования документа JSON из строки, которая в конце содержит посторонние данные.

Примеры использования:

import json

class MyDecoder(json.JSONDecoder):
    def __init__(self):
        json.JSONDecoder.__init__(self, object_hook=self.dict_to_object)

    def dict_to_object(self, d):
        if '__module__' in d and '__class__' in d
            module_name = d.pop('__module__')
            print(f'Подключаем модуль: module = __import__({module_name})')
            class_name = d.pop('__class__')
            print(f'Далее: class = getattr({module_name}, {class_name})')
            args = dict((key.encode('ascii'), value) for key, value in d.items())
            print(f'Аргументы класса {class_name}:', args)
            print(f'Создаем экземпляр: inst = class(**args)')
        else
            raise 'Error DATA'
        return 'inst'

# например в JSON находятся какие-то настройки
data = '

dumps¶

(obj, sort_keys=None, cls=<class ‘json_tricks.encoders.TricksEncoder’>, obj_encoders=, extra_obj_encoders=(), primitives=False, compression=None, allow_nan=False, conv_str_byte=False, fallback_encoders=(), **jsonkwargs)

Convert a nested data structure to a json string.

Parameters:
  • obj – The Python object to convert.
  • sort_keys – Keep this False if you want order to be preserved.
  • cls – The json encoder class to use, defaults to NoNumpyEncoder which gives a warning for numpy arrays.
  • obj_encoders – Iterable of encoders to use to convert arbitrary objects into json-able promitives.
  • extra_obj_encoders – Like obj_encoders but on top of them: use this to add encoders without replacing defaults. Since v3.5 these happen before default encoders.
  • fallback_encoders – These are extra obj_encoders that 1) are ran after all others and 2) only run if the object hasn’t yet been changed.
  • allow_nan – Allow NaN and Infinity values, which is a (useful) violation of the JSON standard (default False).
  • conv_str_byte – Try to automatically convert between strings and bytes (assuming utf-8) (default False).
Returns:

The string containing the json-encoded version of obj.

Other arguments are passed on to cls. Note that sort_keys should be false if you want to preserve order.

Основные методы

Метод json dump

Сериализует в JSON-подобный формат записывая его в (который поддерживает ) используя эту .

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

Модуль всегда создает объекты , не . Следовательно, должен поддерживать ввод .

Когда (по умолчанию), все не-ASCII символы в выводе будут экранированы последовательностями ,. Если , эти символы будут записаны как есть.

Когда (по умолчанию: ), тогда проверка циклических ссылок для типов контейнера будет пропущена, а такие ссылки будут вызывать (или ошибку серьёзнее).

Если (по умолчанию: ), при каждой попытке сериализировать значение , выходящее за допустимые пределы (, , ), будет возникать , в соответствии с сертификацией JSON. В случае если , будут использованы JavaScript аналоги (, , ).

Когда является неотрицательным целым числом или строкой, то объекты и массивы JSON будут выводиться с этим количеством отступов. Если уровень отступа равен 0, отрицательный или , будут использоваться новые строки без отступов. (по умолчанию) отражает наиболее компактное представление. Если строка (например, ), эта строка используется в качестве отступа.

должны быть tuple . По умолчанию используется значение если и при другом значении. Чтобы получить наиболее компактное представление JSON, вы должны указать .

Значение должно быть функцией. Он вызывается для объектов, которые не могут быть сериализованы. Функция должна вернуть кодируемую версию объекта JSON или вызывать . Если не указано, возникает ошибка .

Если (по умолчанию: ), ключи выводимого словаря будут отсортированы.

Чтобы использовать собственный подкласс (например, тот который переопределяет метод для сериализации дополнительных типов), укажите его с помощью аргумента ; в противном случае используется .

Метод json dumps

Сериализирует в строку формата JSON с помощью . Аргументы имеют то же значение, что и для .

Ключи в парах ключ/значение всегда являются строками. Когда словарь конвертируется в JSON, все ключи словаря преобразовываются в строки. Если в результате, сначала конвертировать его в JSON, а потом обратно, новый в словарь может отличаться от, то можно получить словарь идентичный исходному. Другими словами, если x имеет не строковые ключи.

Метод json load

Десериализует из (текстовый или бинарный файл, который поддерживает метод и содержит JSON документ) в объект Python используя эту таблицу конвертации.

— опциональная функция, которая применяется к результату декодирования объекта. Использоваться будет значение, возвращаемое этой функцией, а не полученный словарь . Эта функция используется для реализации пользовательских декодеров (например JSON-RPC).

— опциональная функция, которая применяется к результату декодирования объекта с определенной последовательностью пар ключ/значение. Вместо исходного словаря будет использоваться результат, возвращаемый функцией. Эта функция используется для реализации пользовательских декодеров. Если задан , будет в приоритете.

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

В случае определения , он будет вызван для декодирования строк JSON int. По умолчанию, эквивалентен . Можно использовать другой тип данных или парсер для этого значения (например ).

В случае определения , он будет вызван для строк: , , . Может быть использован для вызова исключений при обнаружении недопустимых чисел JSON. больше не вызывается при .

Чтобы использовать собственный подкласс , укажите его с помощью аргумента ; в противном случае используется . Дополнительные аргументы ключевого слова будут переданы конструктору класса.

Если десериализованные данные не являются допустимым документом JSON, возникнет .

Метод json loads

Десериализует (экземпляр , или , содержащий JSON документ) в объект Python используя таблицу конвертации.

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

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

Standard Compliance and Interoperability¶

The JSON format is specified by RFC 7159 and by
ECMA-404.
This section details this module’s level of compliance with the RFC.
For simplicity, and subclasses, and
parameters other than those explicitly mentioned, are not considered.

This module does not comply with the RFC in a strict fashion, implementing some
extensions that are valid JavaScript but not valid JSON. In particular:

  • Infinite and NaN number values are accepted and output;
  • Repeated names within an object are accepted, and only the value of the last
    name-value pair is used.

Since the RFC permits RFC-compliant parsers to accept input texts that are not
RFC-compliant, this module’s deserializer is technically RFC-compliant under
default settings.

Character Encodings

The RFC recommends that JSON be represented using either UTF-8, UTF-16, or
UTF-32, with UTF-8 being the recommended default for maximum interoperability.

As permitted, though not required, by the RFC, this module’s serializer sets
ensure_ascii=True by default, thus escaping the output so that the resulting
strings only contain ASCII characters.

Other than the ensure_ascii parameter, this module is defined strictly in
terms of conversion between Python objects and
, and thus does not otherwise directly address
the issue of character encodings.

The RFC prohibits adding a byte order mark (BOM) to the start of a JSON text,
and this module’s serializer does not add a BOM to its output.
The RFC permits, but does not require, JSON deserializers to ignore an initial
BOM in their input. This module’s deserializer will ignore an initial BOM, if
present.

Changed in version 3.6.0: Older versions would raise when an initial BOM is present

The RFC does not explicitly forbid JSON strings which contain byte sequences
that don’t correspond to valid Unicode characters (e.g. unpaired UTF-16
surrogates), but it does note that they may cause interoperability problems.
By default, this module accepts and outputs (when present in the original
) codepoints for such sequences.

Infinite and NaN Number Values

The RFC does not permit the representation of infinite or NaN number values.
Despite that, by default, this module accepts and outputs ,
, and as if they were valid JSON number literal values:

>>> # Neither of these calls raises an exception, but the results are not valid JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # Same when deserializing
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan

In the serializer, the allow_nan parameter can be used to alter this
behavior. In the deserializer, the parse_constant parameter can be used to
alter this behavior.

Repeated Names Within an Object

The RFC specifies that the names within a JSON object should be unique, but
does not mandate how repeated names in JSON objects should be handled. By
default, this module does not raise an exception; instead, it ignores all but
the last name-value pair for a given name:

>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json) == {'x' 3}
True

The object_pairs_hook parameter can be used to alter this behavior.

Top-level Non-Object, Non-Array Values

The old version of JSON specified by the obsolete RFC 4627 required that
the top-level value of a JSON text must be either a JSON object or array
(Python or ), and could not be a JSON null,
boolean, number, or string value. RFC 7159 removed that restriction, and
this module does not and has never implemented that restriction in either its
serializer or its deserializer.

Regardless, for maximum interoperability, you may wish to voluntarily adhere
to the restriction yourself.

Testing

The library has comprehensive tests. There are tests against fixtures in the
JSONTestSuite and
nativejson-benchmark
repositories. It is tested to not crash against the
Big List of Naughty Strings.
It is tested to not leak memory. It is tested to not crash
against and not accept invalid UTF-8. There are integration tests
exercising the library’s use in web servers (gunicorn using multiprocess/forked
workers) and when
multithreaded. It also uses some tests from the ultrajson library.

orjson is the most correct of the compared libraries. This graph shows how each
library handles a combined 342 JSON fixtures from the
JSONTestSuite and
nativejson-benchmark tests:

Library Invalid JSON documents not rejected Valid JSON documents not deserialized
orjson
ujson 38
rapidjson 6
simplejson 13
json 17

This shows that all libraries deserialize valid JSON but only orjson
correctly rejects the given invalid JSON fixtures. Errors are largely due to
accepting invalid strings and numbers.

The graph above can be reproduced using the script.

Стандартное соответствие и совместимость

Формат JSON указан в RFC 7159 и ECMA-404. В этом разделе описывается уровень соответствия этого модуля с RFC

Для упрощения, подклассы и , и параметры, которые отличаются от указанных, не берутся во внимание

Этот модуль не соответствует RFC, устанавливая некоторые расширения, которые являются рабочими для JavaScript, но недействительными для JSON. В частности:

  • и принимаются и выводятся;
  • Повторяемые имена внутри объекта принимаются и выводятся, но только последнее значение дублируемого ключа.

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

Декодировка символов

RFC требует, чтобы JSON был представлен с использованием UTF-8, UTF-16 или UTF-32, при том, что UTF-8 является рекомендуемым по умолчанию для максимальной совместимости.

Возможно, но не обязательно для RFC, сериализаторы этого модуля устанавливают по умолчанию, таким образом строки содержат только символы ASCII.

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

RFC запрещает маркер последовательности байтов (BOM) в начало текста JSON и сериализатор этого модуля не добавляет BOM. RFC позволет, не не требует десериализаторы JSON игнорировать BOM на входе. Десериализатор этого модуля вызывает при наличии BOM.

RFC явно не запрещает строки JSON, содержащие последовательность байт, которая не соответствует валидным символам Unicode (например, непарные UTF-16 заменители), он отмечает — они могут вызывать проблемы совместимости. По умолчанию этот модуль принимает и выводит (если есть в исходной строке) специальные последовательности кода.

Infinite и NaN

RFC не допускает представления для значений или . Несмотря на это, по умолчанию этот модуль принимает и выводит , , и , как если бы они были действительно буквальными значениями числа в JSON:

Копировать

В сериализаторе параметр используется для изменения этого поведения. В десериализаторе параметр этот переметр — .

Повторяющиеся имена внутри объекта

RFC указывает, что имена в объекте JSON должны быть уникальными, но не указывает, как должны обрабатываться повторяющиеся имена в объектах JSON. По умолчанию этот модуль не вызывает исключения; вместо этого он игнорирует все, кроме последней пары ключ/значение для данного ключа:

Копировать

Параметр может использоваться для изменения этого.

Значение верхнего уровня Non-Object, Non-Array

Старая версия JSON указанная устаревшим RFC 4627 требовала, чтобы значение верхнего уровня текста JSON было объектом JSON или массивом (Python или ), или не было . RFC 7159 убрало это ограничение, поэтому этот модуль не выполнял и никогда не применял это ограничение ни в своем сериализаторе, ни в десериализаторе.

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

Ограничения реализации

Некоторые реализации десериализатора JSON имеют лимиты на:

  • размер принимаемого текста JSON
  • максимальный уровень вложенности объектов и массивов JSON
  • диапазон и точность чисел JSON
  • содержание и максимальная длина строк JSON

Этот модуль не ставит никаких ограничений, кроме тех, которые относятся к соответствующим типам Python или самому интерпретатору Python.

При сериализации в JSON будьте осторожны с такими ограничениями в приложениях, которые могут потреблять ваш JSON. В частности, числа в JSON часто десериализуются в числа двойной точности IEEE 754 и подвержены ограничениям диапазона и точности этого представления. Это особенно актуально при сериализации значений Python чрезвычайно большой величины или при сериализации экземпляров «необычных» числовых типов, таких как .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *