18.2。 json —JSONエンコーダーとデコーダー
バージョン2.6の新機能。
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(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO 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, separators=(',', ': '))
{
"4": 5,
"6": 7
}
JSONのデコード:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'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 -mjson.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シリアライザーとしても使用できます。
18.2.1。 基本的な使用法
- json.dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw)
この変換テーブル[ X147X]。
skipkeys がtrue(デフォルト:
False
)の場合、基本タイプではないdictキー( str 、 unicode 、 ] int 、 long 、 float 、 bool 、None
)は、TypeError
を上げる代わりに、スキップされます。 。sure_ascii がtrue(デフォルト)の場合、出力内のすべての非ASCII文字は
\uXXXX
シーケンスでエスケープされ、結果はASCIIで構成される str インスタンスになります。文字のみ。 sure_ascii がfalseの場合、 fp に書き込まれるチャンクの一部は unicode インスタンスである可能性があります。 これは通常、入力にUnicode文字列が含まれているか、 encoding パラメーターが使用されているために発生します。fp.write()
が unicode を明示的に理解しない限り( codecs.getwriter()のように)、これによりエラーが発生する可能性があります。check_circular がfalse(デフォルト:
True
)の場合、コンテナータイプの循環参照チェックはスキップされ、循環参照はOverflowError
(またはそれ以下)になります。 。allow_nan がfalse(デフォルト:
True
)の場合、範囲外の float 値( [ X134X]、inf
、-inf
)、JSON仕様に厳密に準拠しています。 allow_nan がtrueの場合、同等のJavaScript(NaN
、Infinity
、-Infinity
)が使用されます。indent が負でない整数の場合、JSON配列要素とオブジェクトメンバーはそのインデントレベルできれいに出力されます。 インデントレベルが0または負の場合、改行のみが挿入されます。
None
(デフォルト)は最もコンパクトな表現を選択します。ノート
デフォルトの項目区切り文字は
', '
であるため、インデントが指定されている場合、出力に末尾の空白が含まれる場合があります。 これを回避するには、separators=(',', ': ')
を使用できます。指定する場合、セパレーターは
(item_separator, key_separator)
タプルである必要があります。 デフォルトでは、(', ', ': ')
が使用されます。 最もコンパクトなJSON表現を取得するには、(',', ':')
を指定して空白を削除する必要があります。encoding はstrインスタンスの文字エンコードであり、デフォルトはUTF-8です。
指定する場合、 default は、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数である必要があります。 オブジェクトのJSONエンコード可能なバージョンを返すか、
TypeError
を発生させる必要があります。 指定しない場合、TypeError
が発生します。sort_keys がtrue(デフォルト:
False
)の場合、辞書の出力はキーでソートされます。カスタム JSONEncoder サブクラスを使用するには(例:
default()
メソッドをオーバーライドして追加の型をシリアル化するもの)、 cls kwargで指定します。 それ以外の場合は、 JSONEncoder が使用されます。
- json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw)
この変換テーブルを使用して、 obj をJSON形式の str にシリアル化します。 sure_ascii がfalseの場合、結果に非ASCII文字が含まれる可能性があり、戻り値は unicode インスタンスである可能性があります。
引数は dump()と同じ意味です。
ノート
JSONのキー/値ペアのキーは、常に str タイプです。 辞書がJSONに変換されると、辞書のすべてのキーが文字列に強制されます。 この結果、辞書がJSONに変換されてから辞書に戻されると、辞書が元の辞書と一致しない場合があります。 つまり、xに文字列以外のキーがある場合は
loads(dumps(x)) != x
です。
- json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
この変換テーブルを使用して、 fp (
.read()
-JSONドキュメントを含むファイルのようなオブジェクトをサポート)をPythonオブジェクトに逆シリアル化します。fp のコンテンツがUTF-8以外のASCIIベースのエンコーディングでエンコードされている場合(例: latin-1)の場合、適切な encoding 名を指定する必要があります。 ASCIIベースではないエンコーディング(UCS-2など)は許可されていないため、
codecs.getreader(encoding)(fp)
でラップするか、 unicode オブジェクトにデコードして loads( )。object_hook は、デコードされたオブジェクトリテラル( dict )の結果とともに呼び出されるオプションの関数です。 dict の代わりに、 object_hook の戻り値が使用されます。 この機能は、カスタムデコーダーを実装するために使用できます(例: JSON-RPC クラスヒント)。
object_pairs_hook はオプションの関数であり、ペアの順序付きリストでデコードされたオブジェクトリテラルの結果とともに呼び出されます。 dict の代わりに、 object_pairs_hook の戻り値が使用されます。 この機能を使用して、キーと値のペアがデコードされる順序に依存するカスタムデコーダーを実装できます(たとえば、 collections.OrderedDict()は挿入の順序を記憶します)。 object_hook も定義されている場合、 object_pairs_hook が優先されます。
バージョン2.7で変更: 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番号が検出された場合に例外を発生させるために使用できます。バージョン2.7で変更: parse_constant は、「null」、「true」、「false」で呼び出されなくなりました。
カスタム JSONDecoder サブクラスを使用するには、
cls
kwargで指定します。 それ以外の場合は、 JSONDecoder が使用されます。 追加のキーワード引数は、クラスのコンストラクターに渡されます。
- json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
この変換テーブルを使用して、 s (JSONドキュメントを含む str または unicode インスタンス)をPythonオブジェクトに逆シリアル化します。
s が str インスタンスであり、UTF-8以外のASCIIベースのエンコーディングでエンコードされている場合(例: latin-1)の場合、適切な encoding 名を指定する必要があります。 ASCIIベースではないエンコーディング(UCS-2など)は許可されていないため、最初に unicode にデコードする必要があります。
他の引数は、 load()と同じ意味です。
18.2.2。 エンコーダーとデコーダー
- class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])
シンプルなJSONデコーダー。
デフォルトでは、デコード時に次の変換を実行します。
JSON
Python
物体
dict
配列
リスト
ストリング
ユニコード
数値(int)
int、long
数(実数)
浮く
NS
NS
NS
NS
ヌル
なし
また、
NaN
、Infinity
、および-Infinity
を、対応するfloat
値として認識します。これは、JSON仕様の範囲外です。encoding は、このインスタンス(デフォルトではUTF-8)によってデコードされた str オブジェクトの解釈に使用されるエンコーディングを決定します。 unicode オブジェクトをデコードする場合は効果がありません。
現在、ASCIIのスーパーセットであるエンコーディングのみが機能することに注意してください。他のエンコーディングの文字列は、 unicode として渡す必要があります。
object_hook が指定されている場合は、デコードされたすべてのJSONオブジェクトの結果とともに呼び出され、指定された dict の代わりにその戻り値が使用されます。 これは、カスタムの逆シリアル化を提供するために使用できます(例: JSON-RPCクラスヒントをサポートするため)。
object_pairs_hook が指定されている場合は、ペアの順序付きリストでデコードされたすべてのJSONオブジェクトの結果とともに呼び出されます。 dict の代わりに、 object_pairs_hook の戻り値が使用されます。 この機能を使用して、キーと値のペアがデコードされる順序に依存するカスタムデコーダーを実装できます(たとえば、 collections.OrderedDict()は挿入の順序を記憶します)。 object_hook も定義されている場合、 object_pairs_hook が優先されます。
バージョン2.7で変更: 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ドキュメントでない場合、
ValueError
が発生します。
- class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])
Pythonデータ構造用の拡張可能なJSONエンコーダー。
デフォルトで次のオブジェクトとタイプをサポートします。
Python
JSON
dict
物体
リスト、タプル
配列
str、unicode
ストリング
int、long、float
番号
NS
NS
NS
NS
なし
ヌル
これを拡張して他のオブジェクトを認識するには、 default()メソッドをサブクラス化して、可能であれば
o
のシリアル化可能なオブジェクトを返す別のメソッドで実装します。それ以外の場合は、スーパークラス実装を呼び出す必要があります(発生させるため)TypeError
)。skipkeys がfalse(デフォルト)の場合、str、int、long、float、または
None
以外のキーのエンコードを試みるのはTypeError
です。 skipkeys がtrueの場合、そのような項目は単にスキップされます。sure_ascii がtrue(デフォルト)の場合、出力内のすべての非ASCII文字は
\uXXXX
シーケンスでエスケープされ、結果はASCII文字で構成される str インスタンスになります。それだけ。 sure_ascii がfalseの場合、結果は unicode インスタンスである可能性があります。 これは通常、入力にUnicode文字列が含まれている場合、または encoding パラメーターが使用されている場合に発生します。check_circular がtrue(デフォルト)の場合、リスト、ディクテーション、およびカスタムエンコードされたオブジェクトは、無限再帰(
OverflowError
が発生する)を防ぐために、エンコード中に循環参照がチェックされます。 それ以外の場合、そのようなチェックは行われません。allow_nan がtrue(デフォルト)の場合、
NaN
、Infinity
、および-Infinity
はそのようにエンコードされます。 この動作はJSON仕様に準拠していませんが、ほとんどのJavaScriptベースのエンコーダーおよびデコーダーと一致しています。 それ以外の場合、そのようなフロートをエンコードするのはValueError
になります。sort_keys がtrue(デフォルト:
False
)の場合、辞書の出力はキーでソートされます。 これは、JSONシリアル化を日常的に比較できることを確認するための回帰テストに役立ちます。indent が負でない整数(デフォルトでは
None
)の場合、JSON配列要素とオブジェクトメンバーはそのインデントレベルできれいに出力されます。 インデントレベルが0の場合、改行のみが挿入されます。None
は最もコンパクトな表現です。ノート
デフォルトの項目区切り文字は
', '
であるため、インデントが指定されている場合、出力に末尾の空白が含まれる場合があります。 これを回避するには、separators=(',', ': ')
を使用できます。指定する場合、セパレーターは
(item_separator, key_separator)
タプルである必要があります。 デフォルトでは、(', ', ': ')
が使用されます。 最もコンパクトなJSON表現を取得するには、(',', ':')
を指定して空白を削除する必要があります。指定する場合、 default は、他の方法ではシリアル化できないオブジェクトに対して呼び出される関数である必要があります。 オブジェクトのJSONエンコード可能なバージョンを返すか、
TypeError
を発生させる必要があります。 指定しない場合、TypeError
が発生します。encoding が
None
でない場合、すべての入力文字列は、JSONエンコードの前にそのエンコーディングを使用してUnicodeに変換されます。 デフォルトはUTF-8です。- 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 JSONEncoder.default(self, o)
- encode(o)
Pythonデータ構造のJSON文字列表現 o を返します。 例えば:
>>> JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
- iterencode(o)
指定されたオブジェクト o をエンコードし、使用可能な場合は各文字列表現を生成します。 例えば:
for chunk in JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
18.2.3。 標準のコンプライアンスと相互運用性
JSON形式は、 RFC 7159 および ECMA-404 で指定されています。 このセクションでは、このモジュールのRFCへの準拠レベルについて詳しく説明します。 簡単にするために、 JSONEncoder および JSONDecoder サブクラス、および明示的に言及されているもの以外のパラメーターは考慮されません。
このモジュールは厳密な方法でRFCに準拠しておらず、有効なJavaScriptであるが有効なJSONではないいくつかの拡張機能を実装しています。 特に:
- 無限数とNaN数の値が受け入れられ、出力されます。
- オブジェクト内で繰り返される名前が受け入れられ、最後の名前と値のペアの値のみが使用されます。
RFCは、RFC準拠のパーサーがRFC準拠ではない入力テキストを受け入れることを許可しているため、このモジュールのデシリアライザーは、デフォルト設定で技術的にRFC準拠です。
18.2.3.1。 文字エンコード
RFCでは、JSONをUTF-8、UTF-16、またはUTF-32のいずれかを使用して表す必要があります。相互運用性を最大化するには、UTF-8が推奨されるデフォルトです。 したがって、このモジュールは、 encoding パラメーターのデフォルトとしてUTF-8を使用します。
このモジュールのデシリアライザーは、ASCII互換のエンコーディングでのみ直接機能します。 UTF-16、UTF-32、およびその他のASCII互換のエンコーディングでは、デシリアライザの encoding パラメータのドキュメントに記載されている回避策を使用する必要があります。
RFCで許可されていますが、必須ではありませんが、このモジュールのシリアライザーはデフォルトで sure_ascii = True を設定し、結果の文字列にASCII文字のみが含まれるように出力をエスケープします。
RFCは、JSONテキストの先頭にバイトオーダーマーク(BOM)を追加することを禁止しており、このモジュールのシリアライザーはその出力にBOMを追加しません。 RFCは、JSONデシリアライザーが入力の最初のBOMを無視することを許可しますが、必須ではありません。 このモジュールのデシリアライザーは、最初のBOMが存在する場合にValueError
を発生させます。
RFCは、有効なUnicode文字に対応しないバイトシーケンスを含むJSON文字列を明示的に禁止していません(例: 対になっていないUTF-16サロゲート)が、相互運用性の問題を引き起こす可能性があることに注意してください。 デフォルトでは、このモジュールはそのようなシーケンスのコードポイントを受け入れて出力します(元の str に存在する場合)。
18.2.3.2。 無限および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 パラメーターを使用してこの動作を変更できます。
18.2.3.3。 オブジェクト内で繰り返される名前
RFCは、JSONオブジェクト内の名前は一意である必要があることを指定していますが、JSONオブジェクト内で繰り返される名前の処理方法を義務付けていません。 デフォルトでは、このモジュールは例外を発生させません。 代わりに、指定された名前の最後の名前と値のペアを除くすべてを無視します。
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{u'x': 3}
object_pairs_hook パラメーターを使用して、この動作を変更できます。
18.2.3.4。 トップレベルの非オブジェクト、非配列値
廃止された RFC 4627 によって指定された古いバージョンのJSONでは、JSONテキストの最上位値がJSONオブジェクトまたは配列のいずれかである必要がありました(Python dict [X180X ]またはlist
)であり、JSON null、ブール値、数値、または文字列値にすることはできません。 RFC 7159 はその制限を削除しました。このモジュールは、シリアライザーまたはデシリアライザーのいずれにもその制限を実装していません。
とにかく、相互運用性を最大化するために、自分で制限を自主的に順守することをお勧めします。
18.2.3.5。 実装の制限
一部のJSONデシリアライザーの実装では、以下に制限が設定される場合があります。
- 受け入れられるJSONテキストのサイズ
- JSONオブジェクトと配列のネストの最大レベル
- JSON番号の範囲と精度
- JSON文字列の内容と最大長
このモジュールは、関連するPythonデータ型自体またはPythonインタープリター自体の制限を超えてそのような制限を課すことはありません。
JSONにシリアル化するときは、JSONを消費する可能性のあるアプリケーションでのそのような制限に注意してください。 特に、JSON番号がIEEE 754倍精度番号に逆シリアル化されるのが一般的であるため、その表現の範囲と精度の制限が適用されます。 これは、非常に大きな大きさのPython int 値をシリアル化する場合、または decimal.Decimal などの「エキゾチック」な数値型のインスタンスをシリアル化する場合に特に関係があります。
脚注
- 1
- RFC 7159 の正誤表に記載されているように、JSONは文字列内のリテラルU + 2028(LINE SEPARATOR)およびU + 2029(PARAGRAPH SEPARATOR)文字を許可しますが、JavaScript(ECMAScript Edition 5.1以降)は許可しません。