json — JSONエンコーダーおよびデコーダー—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/json
移動先:案内検索

json —JSONエンコーダーおよびデコーダー

ソースコード: :source: `Lib / json / __ init __。py`



JSON(JavaScript Object Notation) RFC 7159 RFC 4627 は廃止)および[X72X]で指定X136X] ECMA-404 は、 JavaScript オブジェクトリテラル構文に触発された軽量のデータ交換形式です(ただし、JavaScript 1 の厳密なサブセットではありません)。

json は、標準ライブラリ marshal および pickle モジュールのユーザーに馴染みのあるAPIを公開します。

基本的な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]
...         # Let the base class default method raise the TypeError
...         return json.JSONEncoder.default(self, 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のサブセットです。 このモジュールのデフォルト設定(特に、デフォルトの Separators 値)によって生成されるJSONも、YAML1.0および1.1のサブセットです。 したがって、このモジュールはYAMLシリアライザーとしても使用できます。


ノート

このモジュールのエンコーダーとデコーダーは、デフォルトで入力と出力の順序を保持します。 基になるコンテナが順序付けされていない場合にのみ、順序が失われます。

Python 3.7より前は、 dict の順序が保証されていなかったため、 collections.OrderedDict が特に要求されない限り、入力と出力は通常スクランブルされていました。 Python 3.7以降、通常の dict が順序を保持するようになったため、JSONの生成と解析に collections.OrderedDict を指定する必要がなくなりました。


基本的な使用法

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)

この変換テーブル[ X147X]。

skipkeys がtrue(デフォルト:False)の場合、基本タイプではないdictキー( strint] floatboolNone)は、 TypeError を発生させる代わりに、スキップされます。

json モジュールは、 bytes オブジェクトではなく、常に str オブジェクトを生成します。 したがって、fp.write()str 入力をサポートする必要があります。

sure_ascii がtrue(デフォルト)の場合、出力にはすべての着信非ASCII文字がエスケープされることが保証されます。 sure_ascii がfalseの場合、これらの文字はそのまま出力されます。

check_circular がfalse(デフォルト:True)の場合、コンテナータイプの循環参照チェックはスキップされ、循環参照はオーバーフローエラー(またはそれ以上)になります。 )。

allow_nan がfalse(デフォルト:True)の場合、範囲外の float 値(naninf-inf)、JSON仕様に厳密に準拠しています。 allow_nan がtrueの場合、同等のJavaScript(NaNInfinity-Infinity)が使用されます。

indent が負でない整数または文字列の場合、JSON配列要素とオブジェクトメンバーはそのインデントレベルできれいに出力されます。 インデントレベルが0、負、または""の場合、改行のみが挿入されます。 None(デフォルト)は最もコンパクトな表現を選択します。 正の整数インデントを使用すると、レベルごとに多くのスペースがインデントされます。 indent が文字列("\t"など)の場合、その文字列を使用して各レベルがインデントされます。

バージョン3.2で変更:整数に加えてインデントの文字列を許可します。

指定する場合、セパレーター(item_separator, key_separator)タプルである必要があります。 インデントNoneの場合、デフォルトは(', ', ': ')であり、それ以外の場合は(',', ': ')です。 最もコンパクトなJSON表現を取得するには、(',', ':')を指定して空白を削除する必要があります。

バージョン3.4で変更: インデントNoneでない場合は、デフォルトとして(',', ': ')を使用します。

指定する場合、 default は、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数である必要があります。 オブジェクトのJSONエンコード可能なバージョンを返すか、 TypeError を発生させる必要があります。 指定しない場合、 TypeError が発生します。

sort_keys がtrue(デフォルト:False)の場合、辞書の出力はキーでソートされます。

カスタム JSONEncoder サブクラスを使用するには(例: default()メソッドをオーバーライドして追加の型をシリアル化するもの)、 cls kwargで指定します。 それ以外の場合は、 JSONEncoder が使用されます。

バージョン3.6で変更:すべてのオプションパラメータがキーワードのみになりました。

ノート

picklemarshal とは異なり、JSONはフレーム化されたプロトコルではないため、同じ fpを使用して dump()を繰り返し呼び出して複数のオブジェクトをシリアル化しようとしますは無効なJSONファイルになります。

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に変換されてから辞書に戻されると、辞書が元の辞書と一致しない場合があります。 つまり、xに文字列以外のキーがある場合はloads(dumps(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.read() -JSONドキュメントを含むテキストファイルまたはバイナリファイルをサポート)をPythonオブジェクトに逆シリアル化しますテーブル。

object_hook は、デコードされたオブジェクトリテラル( dict )の結果とともに呼び出されるオプションの関数です。 dict の代わりに、 object_hook の戻り値が使用されます。 この機能は、カスタムデコーダーを実装するために使用できます(例: JSON-RPC クラスヒント)。

object_pairs_hook はオプションの関数であり、ペアの順序付きリストでデコードされたオブジェクトリテラルの結果とともに呼び出されます。 dict の代わりに、 object_pairs_hook の戻り値が使用されます。 この機能は、カスタムデコーダーを実装するために使用できます。 object_hook も定義されている場合、 object_pairs_hook が優先されます。

バージョン3.1で変更: object_pairs_hook のサポートが追加されました。

parse_float が指定されている場合、デコードされるすべてのJSON浮動小数点の文字列とともに呼び出されます。 デフォルトでは、これはfloat(num_str)と同等です。 これは、JSONフロートに別のデータ型またはパーサーを使用するために使用できます(例: decimal.Decimal )。

parse_int が指定されている場合、デコードされるすべてのJSONintの文字列とともに呼び出されます。 デフォルトでは、これは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である必要があります。

json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

この変換テーブルを使用して、 s strbytes 、または bytearray インスタンス(JSONドキュメントを含む))をPythonオブジェクトに逆シリアル化します。 。

他の引数は load()と同じ意味ですが、Python3.1以降無視され非推奨となった encoding を除きます。

デシリアライズされるデータが有効なJSONドキュメントでない場合、 JSONDecodeError が発生します。

バージョン3.6での変更: s は、タイプ bytes または bytearray になりました。 入力エンコーディングは、UTF-8、UTF-16、またはUTF-32である必要があります。


エンコーダーとデコーダー

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

配列

リスト

ストリング

str

数値(int)

int

数(実数)

浮く

NS

NS

NS

NS

ヌル

なし

また、NaNInfinity、および-Infinityを、対応するfloat値として認識します。これは、JSON仕様の範囲外です。

object_hook が指定されている場合、デコードされたすべてのJSONオブジェクトの結果とともに呼び出され、指定された dict の代わりにその戻り値が使用されます。 これは、カスタムの逆シリアル化を提供するために使用できます(例: JSON-RPCクラスヒントをサポートするため)。

object_pairs_hook が指定されている場合は、ペアの順序付きリストでデコードされたすべてのJSONオブジェクトの結果とともに呼び出されます。 dict の代わりに、 object_pairs_hook の戻り値が使用されます。 この機能は、カスタムデコーダーを実装するために使用できます。 object_hook も定義されている場合、 object_pairs_hook が優先されます。

バージョン3.1で変更: object_pairs_hook のサポートが追加されました。

parse_float が指定されている場合、デコードされるすべてのJSON浮動小数点の文字列とともに呼び出されます。 デフォルトでは、これはfloat(num_str)と同等です。 これは、JSONフロートに別のデータ型またはパーサーを使用するために使用できます(例: decimal.Decimal )。

parse_int が指定されている場合、デコードされるすべてのJSONintの文字列とともに呼び出されます。 デフォルトでは、これはint(num_str)と同等です。 これは、JSON整数に別のデータ型またはパーサーを使用するために使用できます(例: float )。

parse_constant は、指定されている場合、'-Infinity''Infinity''NaN'のいずれかの文字列で呼び出されます。 これは、無効なJSON番号が検出された場合に例外を発生させるために使用できます。

strict がfalseの場合(Trueがデフォルト)、制御文字は文字列内で許可されます。 このコンテキストでの制御文字は、'\t'(タブ)、'\n''\r''\0'など、0〜31の範囲の文字コードを持つ文字です。

デシリアライズされるデータが有効なJSONドキュメントでない場合、 JSONDecodeError が発生します。

バージョン3.6で変更:すべてのパラメーターがキーワードのみになりました。

decode(s)

s (JSONドキュメントを含む str インスタンス)のPython表現を返します。

指定されたJSONドキュメントが無効な場合、 JSONDecodeError が発生します。

raw_decode(s)

s (JSONドキュメントで始まる str )からJSONドキュメントをデコードし、Python表現の2タプルと 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)

Pythonデータ構造用の拡張可能なJSONエンコーダー。

デフォルトで次のオブジェクトとタイプをサポートします。

Python

JSON

dict

オブジェクト

リスト、タプル

配列

str

ストリング

int、float、intおよびfloatから派生した列挙型

番号

NS

NS

NS

NS

なし

ヌル

バージョン3.4で変更: intおよびfloatから派生したEnumクラスのサポートが追加されました。

これを拡張して他のオブジェクトを認識するには、 default()メソッドをサブクラス化して、可能であればoのシリアル化可能なオブジェクトを返す別のメソッドで実装します。それ以外の場合は、スーパークラス実装を呼び出す必要があります(発生させるため) TypeError )。

skipkeys がfalse(デフォルト)の場合、 strint 、以外のキーのエンコードを試みるのは TypeError です。 フロートまたはNoneskipkeys がtrueの場合、そのような項目は単にスキップされます。

sure_ascii がtrue(デフォルト)の場合、出力にはすべての着信非ASCII文字がエスケープされることが保証されます。 sure_ascii がfalseの場合、これらの文字はそのまま出力されます。

check_circular がtrue(デフォルト)の場合、リスト、ディクテーション、およびカスタムエンコードされたオブジェクトは、無限再帰を防ぐためにエンコード中に循環参照がチェックされます( OverflowError が発生します)。 。 それ以外の場合、そのようなチェックは行われません。

allow_nan がtrue(デフォルト)の場合、NaNInfinity、および-Infinityはそのようにエンコードされます。 この動作はJSON仕様に準拠していませんが、ほとんどのJavaScriptベースのエンコーダーおよびデコーダーと一致しています。 それ以外の場合、そのようなフロートをエンコードするのは ValueError になります。

sort_keys がtrue(デフォルト:False)の場合、辞書の出力はキーでソートされます。 これは、JSONシリアル化を日常的に比較できることを確認するための回帰テストに役立ちます。

indent が負でない整数または文字列の場合、JSON配列要素とオブジェクトメンバーはそのインデントレベルできれいに出力されます。 インデントレベルが0、負、または""の場合、改行のみが挿入されます。 None(デフォルト)は最もコンパクトな表現を選択します。 正の整数インデントを使用すると、レベルごとに多くのスペースがインデントされます。 indent が文字列("\t"など)の場合、その文字列を使用して各レベルがインデントされます。

バージョン3.2で変更:整数に加えてインデントの文字列を許可します。

指定する場合、セパレーター(item_separator, key_separator)タプルである必要があります。 インデントNoneの場合、デフォルトは(', ', ': ')であり、それ以外の場合は(',', ': ')です。 最もコンパクトなJSON表現を取得するには、(',', ':')を指定して空白を削除する必要があります。

バージョン3.4で変更: インデントNoneでない場合は、デフォルトとして(',', ': ')を使用します。

指定する場合、 default は、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数である必要があります。 オブジェクトのJSONエンコード可能なバージョンを返すか、 TypeError を発生させる必要があります。 指定しない場合、 TypeError が発生します。

バージョン3.6で変更:すべてのパラメーターがキーワードのみになりました。

default(o)

このメソッドをサブクラスに実装して、 o のシリアル化可能なオブジェクトを返すか、基本実装を呼び出します( TypeError を発生させるため)。

たとえば、任意のイテレータをサポートするには、次のようにデフォルトを実装できます。

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   # Let the base class default method raise the TypeError
   return json.JSONEncoder.default(self, 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)


例外

exception json.JSONDecodeError(msg, doc, pos)

ValueError のサブクラスで、次の追加属性があります。

msg

フォーマットされていないエラーメッセージ。

doc

解析中のJSONドキュメント。

pos

解析に失敗した doc の開始インデックス。

lineno

pos に対応する行。

colno

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で許可されているが、必須ではないが、このモジュールのシリアライザーはデフォルトで sure_ascii = True を設定し、結果の文字列にASCII文字のみが含まれるように出力をエスケープします。

ensure_ascii パラメーターを除いて、このモジュールはPythonオブジェクトと Unicode文字列の間の変換に関して厳密に定義されているため、文字エンコードの問題に直接対処することはありません。

RFCは、JSONテキストの先頭にバイト順マーク(BOM)を追加することを禁止しており、このモジュールのシリアライザーはその出力にBOMを追加しません。 RFCは、JSONデシリアライザーが入力の最初のBOMを無視することを許可しますが、必須ではありません。 このモジュールのデシリアライザーは、最初のBOMが存在する場合、 ValueError を発生させます。

RFCは、有効なUnicode文字に対応しないバイトシーケンスを含むJSON文字列を明示的に禁止していません(例: 対になっていないUTF-16サロゲート)が、相互運用性の問題を引き起こす可能性があることに注意してください。 デフォルトでは、このモジュールはそのようなシーケンスのコードポイントを受け入れて出力します(元の str に存在する場合)。


無限およびNaNの数値

RFCは、無限またはNaN数の値の表現を許可していません。 それにもかかわらず、デフォルトでは、このモジュールはInfinity-Infinity、およびNaNを、有効なJSON数値リテラル値であるかのように受け入れて出力します。

>>> # 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

シリアライザーでは、 allow_nan パラメーターを使用してこの動作を変更できます。 デシリアライザーでは、 parse_constant パラメーターを使用してこの動作を変更できます。


オブジェクト内で繰り返される名前

RFCは、JSONオブジェクト内の名前は一意である必要があることを指定していますが、JSONオブジェクト内で繰り返される名前の処理方法を義務付けていません。 デフォルトでは、このモジュールは例外を発生させません。 代わりに、指定された名前の最後の名前と値のペアを除くすべてを無視します。

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

object_pairs_hook パラメーターを使用して、この動作を変更できます。


トップレベルの非オブジェクト、非配列値

廃止された RFC 4627 によって指定された古いバージョンのJSONでは、JSONテキストの最上位値がJSONオブジェクトまたは配列のいずれかである必要がありました(Python dict [X180X ]または list )であり、JSON null、ブール値、数値、または文字列値にすることはできません。 RFC 7159 はその制限を削除しました。このモジュールは、シリアライザーまたはデシリアライザーのいずれにもその制限を実装していません。

とにかく、相互運用性を最大化するために、自分で制限を自主的に順守することをお勧めします。


実装の制限

一部のJSONデシリアライザーの実装では、以下に制限が設定される場合があります。

  • 受け入れられるJSONテキストのサイズ
  • JSONオブジェクトと配列のネストの最大レベル
  • JSON番号の範囲と精度
  • JSON文字列の内容と最大長

このモジュールは、関連するPythonデータ型自体またはPythonインタープリター自体の制限を超えてそのような制限を課すことはありません。

JSONにシリアル化するときは、JSONを消費する可能性のあるアプリケーションでのそのような制限に注意してください。 特に、JSON番号がIEEE 754倍精度番号に逆シリアル化されるのが一般的であるため、その表現の範囲と精度の制限が適用されます。 これは、非常に大きな大きさのPython int 値をシリアル化する場合、または decimal.Decimal などの「エキゾチック」な数値型のインスタンスをシリアル化する場合に特に関係があります。


コマンドラインインターフェイス

ソースコード: :source: `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 オプションを使用して、辞書の出力をキーのアルファベット順に並べ替えます。


コマンドラインオプション

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の新機能。

--json-lines

すべての入力行を個別のJSONオブジェクトとして解析します。

バージョン3.8の新機能。

-h, --help
ヘルプメッセージを表示します。

脚注

1
RFC 7159 の正誤表に記載されているように、JSONは文字列内のリテラルU + 2028(LINE SEPARATOR)およびU + 2029(PARAGRAPH SEPARATOR)文字を許可しますが、JavaScript(ECMAScript Edition 5.1以降)は許可しません。