Содержание страницы
json – кодировщик и декодировщик JSON¶json – JSON encoder and decoder
Исходный код: Lib/json/__init__.py
JSON (JavaScript Object Notation), описанный в RFC 7159 (который заменяет RFC 4627) и в ECMA-404, является легковесным форматом обмена данными, вдохновлённым синтаксисом литералов объектов JavaScript (хотя он не является строгим подмножеством JavaScript [1]).
Предупреждение
Соблюдайте осторожность при разборе JSON-данных из ненадёжных источников. Злонамеренная JSON-строка может заставить декодер потреблять значительные ресурсы CPU и памяти. Рекомендуется ограничивать размер разбираемых данных.
json предоставляет API, знакомый пользователям модулей стандартной библиотеки marshal и pickle.
Кодирование иерархий базовых объектов Python:
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
Компактное кодирование:
>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'
Красивое форматирование:
>>> import json
>>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4))
{
"4": 5,
"6": 7
}
Декодирование JSON:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']
Специализированное декодирование объектов JSON:
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')
Расширение JSONEncoder:
>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... # Пусть метод базового класса по умолчанию возбуждает TypeError
... return super().default(obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[2.0', ', 1.0', ']']
Использование json.tool из командной оболочки для проверки и красивого вывода:
$ 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)
Смотрите интерфейс командной строки для подробной документации.
Примечание
JSON является подмножеством YAML 1.2. JSON, создаваемый настройками модуля по умолчанию (в частности, значением separators по умолчанию), также является подмножеством YAML 1.0 и 1.1. Таким образом, этот модуль можно использовать как сериализатор YAML.
Примечание
Кодировщики и декодировщики этого модуля по умолчанию сохраняют порядок ввода и вывода. Порядок теряется только в том случае, если основные контейнеры неупорядочены.
Основное использование¶Basic Usage
- json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶
Сериализует obj в поток в формате JSON в fp (
.write()-поддерживающий файлоподобный объект), используя таблицу преобразования Python в JSON.Примечание
В отличие от
pickleиmarshal, JSON не является фреймовым протоколом, поэтому попытка сериализовать несколько объектов с повторными вызовамиdump()с использованием одного и того же fp приведёт к созданию недопустимого JSON-файла.- Параметры:
obj (object) – Сериализуемый объект Python.
fp (файлоподобный объект) – Файлоподобный объект, в который будет сериализован obj. Модуль
jsonвсегда создаёт объектыstr, а неbytes, поэтомуfp.write()должен поддерживать вводstr.skipkeys (bool) – Если
True, ключи, не являющиеся базовым типом (str,int,float,bool,None), будут пропущены вместо возбужденияTypeError. По умолчаниюFalse.ensure_ascii (bool) – Если
True(по умолчанию), выходные данные гарантированно будут содержать все не-ASCII символы экранированными. ЕслиFalse, эти символы будут выводиться как есть.check_circular (bool) – Если
False, проверка циклических ссылок для контейнерных типов пропускается, и циклическая ссылка приведёт кRecursionError(или хуже). По умолчаниюTrue.allow_nan (bool) – Если
False, сериализация значенийfloatвне допустимого диапазона (nan,inf,-inf) вызоветValueErrorв строгом соответствии со спецификацией JSON. ЕслиTrue(по умолчанию), используются их эквиваленты в JavaScript (NaN,Infinity,-Infinity).cls (подкласс
JSONEncoder) – Если задан, пользовательский кодировщик JSON с переопределённым методомdefault(), для сериализации в пользовательские типы данных. ЕслиNone(по умолчанию), используетсяJSONEncoder.indent (int | str | None) – Если положительное целое число или строка, элементы массива JSON и члены объекта будут отформатированы с отступом этого уровня. Положительное целое число задаёт количество пробелов на уровень; строка (например,
"\t") используется для отступа каждого уровня. Если ноль, отрицательное или""(пустая строка), вставляются только переводы строк. ЕслиNone(по умолчанию), используется наиболее компактное представление.separators (tuple | None) – Кортеж из двух элементов:
(item_separator, key_separator). ЕслиNone(по умолчанию), separators по умолчанию равен(', ', ': '), если indent равенNone, и(',', ': ')в противном случае. Для максимально компактного JSON укажите(',', ':'), чтобы убрать пробелы.default (callable | None) – Функция, вызываемая для объектов, которые иначе не могут быть сериализованы. Она должна возвращать версию объекта, кодируемую в JSON, или возбуждать
TypeError. ЕслиNone(по умолчанию), возбуждаетсяTypeError.sort_keys (bool) – если
True, словари будут выводиться отсортированными по ключам. По умолчаниюFalse.
Изменено в версии 3.2: Разрешено использование строк для indent в дополнение к целым числам.
Изменено в версии 3.4: Используйте
(',', ': ')по умолчанию, если indent не равноNone.Изменено в версии 3.6: Все необязательные параметры теперь являются только ключевыми.
- json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶
Сериализует obj в JSON-форматированную
str, используя эту таблицу преобразования. Аргументы имеют тот же смысл, что и вdump().Примечание
Ключи в парах ключ-значение JSON всегда имеют тип
str. При преобразовании словаря в JSON все его ключи приводятся к строкам. В результате, если словарь преобразовать в JSON, а затем обратно в словарь, полученный словарь может не совпадать с исходным. То естьloads(dumps(x)) != x, если x имеет нестроковые ключи.
- json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶
Десериализует fp в объект Python, используя таблицу преобразования JSON в Python.
- Параметры:
fp (файлоподобный объект) – поддерживающий
.read()текстовый файл или двоичный файл, содержащий JSON-документ для десериализации.cls (подкласс
JSONDecoder) – если задан, пользовательский JSON-декодер. Дополнительные именованные аргументы дляload()будут переданы конструктору cls. ЕслиNone(по умолчанию), используетсяJSONDecoder.object_hook (callable | None) – Если задано, функция, которая вызывается с результатом декодирования любого объектного литерала (
dict). Возвращаемое значение этой функции будет использовано вместоdict. Эту возможность можно использовать для реализации пользовательских декодеров, например, для подсказки класса JSON-RPC. По умолчаниюNone.object_pairs_hook (callable | None) – Если задано, функция, которая вызывается с результатом декодирования любого объектного литерала в виде упорядоченного списка пар. Возвращаемое значение этой функции будет использовано вместо
dict. Эту возможность можно использовать для реализации пользовательских декодеров. Если также задан object_hook, приоритет имеет object_pairs_hook. По умолчаниюNone.parse_float (вызываемый объект | None) – если задан, функция, вызываемая со строкой каждого JSON-числа с плавающей точкой для декодирования. Если
None(по умолчанию), это эквивалентноfloat(num_str). Это может использоваться для парсинга JSON-чисел с плавающей точкой в пользовательские типы данных, например,decimal.Decimal.parse_int (вызываемый объект | None) – если задан, функция, вызываемая со строкой каждого JSON-целого для декодирования. Если
None(по умолчанию), это эквивалентноint(num_str). Это может использоваться для парсинга JSON-целых чисел в пользовательские типы данных, например,float.parse_constant (вызываемый объект | None) – если задан, функция, вызываемая с одной из следующих строк:
'-Infinity','Infinity'или'NaN'. Это может использоваться для возбуждения исключения при обнаружении некорректных JSON-чисел. По умолчаниюNone.
- Возбуждает:
JSONDecodeError – когда десериализуемые данные не являются корректным JSON-документом.
UnicodeDecodeError – когда десериализуемые данные не содержат данные в кодировке UTF-8, UTF-16 или UTF-32.
Изменено в версии 3.1:
Добавлен необязательный параметр object_pairs_hook.
parse_constant больше не вызывается для 'null', 'true', 'false'.
Изменено в версии 3.6:
Все необязательные параметры теперь являются только ключевыми.
fp теперь может быть двоичным файлом. Кодировка входных данных должна быть UTF-8, UTF-16 или UTF-32.
Изменено в версии 3.11: Значение parse_int по умолчанию в
int()теперь ограничивает максимальную длину строки целого числа через ограничение длины преобразования строки целого числа интерпретатора, чтобы помочь избежать атак типа «отказ в обслуживании».
- json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶
Идентично
load(), но вместо файлоподобного объекта десериализует s (экземплярstr,bytesилиbytearray, содержащий JSON-документ) в объект Python, используя эту таблицу преобразования.Изменено в версии 3.6: s теперь может быть типа
bytesилиbytearray. Кодировка входных данных должна быть UTF-8, UTF-16 или UTF-32.Изменено в версии 3.9: Именованный аргумент encoding удален.
Кодировщики и декодеры¶Encoders and Decoders
- class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)¶
Простой JSON-декодер.
По умолчанию выполняет следующие преобразования при декодировании:
JSON
Python
объект
dict
массив
list
строка
str
число (int)
int
число (вещественное)
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). Это позволяет использовать другой тип данных или синтаксический анализатор для чисел с плавающей точкой (например,decimal.Decimal).parse_int – необязательная функция, которая вызывается со строкой каждого декодируемого JSON-целого числа. По умолчанию она эквивалентна
int(num_str). Это позволяет использовать другой тип данных или синтаксический анализатор для целых чисел JSON (например,float).parse_constant – необязательная функция, которая вызывается с одной из следующих строк:
'-Infinity','Infinity','NaN'. Это позволяет вызывать исключение при обнаружении недопустимых чисел JSON.Если strict равно false (по умолчанию
True), то управляющие символы допускаются внутри строк. Под управляющими символами здесь понимаются символы с кодами в диапазоне 0–31, включая'\t'(табуляция),'\n','\r'и'\0'.Если десериализуемые данные не являются корректным JSON-документом, будет вызвано
JSONDecodeError.Изменено в версии 3.6: Все параметры теперь только ключевые.
- decode(s)¶
Возвращает представление s в Python (экземпляр
str, содержащий JSON-документ).JSONDecodeErrorбудет вызвано, если переданный JSON-документ не является корректным.
- raw_decode(s)¶
Декодирует 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
объект
list, tuple
массив
str
строка
int, float, перечисления, производные от int и float
число
True
true
False
false
None
null
Изменено в версии 3.4: Добавлена поддержка классов Enum, производных от int и float.
Чтобы расширить функциональность на другие объекты, создайте подкласс и реализуйте метод
default()с другим методом, который возвращает сериализуемый объект дляo, если это возможно; в противном случае следует вызвать реализацию суперкласса (для возбужденияTypeError).Если skipkeys имеет значение false (по умолчанию), возбуждается
TypeErrorпри попытке кодировать ключи, не являющиесяstr,int,float,boolилиNone. Если skipkeys равно true, такие элементы просто пропускаются.Если ensure_ascii равен true (по умолчанию), то выходные данные гарантированно содержат все входящие не-ASCII-символы экранированными. Если ensure_ascii равен false, эти символы выводятся как есть.
Если check_circular равно true (по умолчанию), то списки, словари и пользовательские объекты проверяются на циклические ссылки во время кодирования для предотвращения бесконечной рекурсии (которая вызвала бы
RecursionError). В противном случае такая проверка не выполняется.Если allow_nan равно true (по умолчанию), то значения
NaN,Infinityи-Infinityкодируются как есть. Такое поведение не соответствует спецификации JSON, но согласуется с большинством кодировщиков и декодировщиков на JavaScript. В противном случае при кодировании таких чисел с плавающей запятой возбуждаетсяValueError.Если sort_keys равно true (по умолчанию
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: Все параметры теперь только ключевые.
- default(o)¶
В подклассе этот метод должен возвращать сериализуемый объект для o или вызывать базовую реализацию (для возбуждения
TypeError).Например, для поддержки произвольных итераторов можно реализовать
default()следующим образом:def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Пусть метод базового класса по умолчанию возбуждает TypeError return super().default(o)
- encode(o)¶
Возвращает строковое представление структуры данных Python в формате JSON, o. Например:
>>> json.JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
- iterencode(o)¶
Кодирует заданный объект o и выдаёт каждое строковое представление по мере готовности. Например:
for chunk in json.JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
Исключения¶Exceptions
- exception json.JSONDecodeError(msg, doc, pos)¶
Подкласс
ValueErrorсо следующими дополнительными атрибутами:- msg¶
Неформатированное сообщение об ошибке.
- doc¶
Разбираемый JSON-документ.
- pos¶
Начальный индекс doc, в котором произошла ошибка разбора.
- lineno¶
Строка, соответствующая pos.
- colno¶
Столбец, соответствующий pos.
Добавлено в версии 3.5.
Соответствие стандартам и интероперабельность¶Standard Compliance and Interoperability
Формат JSON определяется RFC 7159 и ECMA-404.
В этом разделе подробно описывается степень соответствия модуля RFC.
Для простоты JSONEncoder и JSONDecoder подклассы, а также параметры, не указанные явно, не рассматриваются.
Этот модуль не полностью соответствует RFC, реализуя некоторые расширения, которые являются допустимым JavaScript, но недопустимым JSON. В частности:
Бесконечные и NaN числовые значения принимаются и выводятся;
Повторяющиеся имена в объекте принимаются, и используется только значение последней пары.
Поскольку RFC разрешает совместимым с RFC анализаторам принимать входные тексты, которые не соответствуют RFC, десериализатор этого модуля технически соответствует RFC при настройках по умолчанию.
Кодировки символов¶Character Encodings
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 игнорировали начальный BOM во входных данных. Десериализатор этого модуля возбуждает ValueError, когда присутствует начальный BOM.
RFC явно не запрещает строки JSON, содержащие последовательности байтов, которые не соответствуют допустимым символам Unicode (например, непарные суррогаты UTF-16), но отмечает, что они могут вызывать проблемы совместимости.
По умолчанию этот модуль принимает и выводит (когда они присутствуют в исходном str) кодовые точки таких последовательностей.
Бесконечные и NaN числовые значения¶Infinite and NaN Number Values
RFC не допускает представления бесконечных или NaN числовых значений.
Несмотря на это, по умолчанию этот модуль принимает и выводит Infinity, -Infinity и NaN, как если бы они были допустимыми числовыми литералами JSON:
>>> # Ни один из этих вызовов не возбуждает исключение, но результаты не являются корректным JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # То же самое при десериализации
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan
В сериализаторе параметр allow_nan можно использовать для изменения этого поведения. В десериализаторе параметр parse_constant можно использовать для изменения этого поведения.
Повторяющиеся имена внутри объекта¶Repeated Names Within an Object
RFC указывает, что имена внутри JSON-объекта должны быть уникальными, но не предписывает, как обрабатывать повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не вызывает исключение; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
Параметр object_pairs_hook можно использовать для изменения этого поведения.
Значения верхнего уровня, не являющиеся объектами или массивами¶Top-level Non-Object, Non-Array Values
Старая версия JSON, определённая устаревшим RFC 4627, требовала, чтобы
значение верхнего уровня JSON-текста было либо JSON-объектом, либо массивом
(Python dict или list), и не могло быть null, boolean,
числом или строкой. RFC 7159 снял это ограничение, и
этот модуль не реализует и никогда не реализовывал это ограничение ни в своём
сериализаторе, ни в десериализаторе.
Тем не менее, для максимальной совместимости можно добровольно придерживаться этого ограничения.
Ограничения реализации¶Implementation Limitations
Некоторые реализации JSON-десериализаторов могут устанавливать ограничения на:
размер принимаемых JSON-текстов
максимальный уровень вложенности JSON-объектов и массивов
диапазон и точность JSON-чисел
содержимое и максимальную длину JSON-строк
Этот модуль не накладывает никаких подобных ограничений, кроме тех, что присущи соответствующим типам данных Python или самому интерпретатору Python.
При сериализации в JSON учитывайте подобные ограничения в приложениях, которые могут потреблять ваш JSON. В частности, JSON-числа часто десериализуются в числа двойной точности IEEE 754 и, следовательно, подчиняются ограничениям диапазона и точности этого представления. Это особенно актуально при сериализации значений Python int чрезвычайно большой величины или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal.
Интерфейс командной строки¶Command Line Interface
Исходный код: Lib/json/tool.py
Модуль json.tool предоставляет простой интерфейс командной строки для проверки
и форматированного вывода JSON-объектов.
Если необязательные аргументы infile и outfile не указаны,
будут использоваться sys.stdin и sys.stdout соответственно:
$ 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)
Изменено в версии 3.5: Вывод теперь располагается в том же порядке, что и входные данные. Используйте
параметр --sort-keys для сортировки вывода словарей по ключу в алфавитном порядке.
Параметры командной строки¶Command line options
- infile¶
JSON-файл для проверки или красивого вывода:
$ 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 } ]
Если infile не указан, читать из
sys.stdin.
- outfile¶
Записать вывод infile в указанный outfile. В противном случае записать его в
sys.stdout.
- --sort-keys¶
Сортировать вывод словарей по ключу в алфавитном порядке.
Добавлено в версии 3.5.
- --no-ensure-ascii¶
Отключает экранирование не-ASCII символов; подробнее см.
json.dumps().Добавлено в версии 3.9.
- --json-lines¶
Анализировать каждую входную строку как отдельный JSON-объект.
Добавлено в версии 3.8.
- --indent, --tab, --no-indent, --compact¶
Взаимоисключающие опции для управления пробелами.
Добавлено в версии 3.9.
- -h, --help¶
Показывает справочное сообщение.
Сноски
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.