モジュールのpython3詳細なJSON

この記事の紹介のpython3詳細なJSONモジュールの用途は、小扁は、共有への皆のために、今、非常に良い感じが、また、基準となります。是非、ご覧ください、一緒に小さなシリーズに従うこと

1.概要

JSON(JavaScript Object Notation)は広く使用されているデータフォーマット軽量である。Pythonの標準ライブラリモジュールの機能を処理するJSON JSONデータを提供する。
非常に基本的なデータ構造内ザPythonは、共通辞書(辞書)である。これ次のように典型的な構造は以下の通りであります:

d = {
'a': 123,
'b': {
'x': ['A', 'B', 'C']
}
}

JSONと、次のように構成されています。

{
"a": 123,
"b": {
"x": ["A", "B", "C"]
}
}

私たちが見ることができ、辞書やJSONは非常に接近している、とJSONライブラリでのPythonの主な機能は提供していますが、また2間の遷移。

2.読むJSON

json.loads方法は、JSONのstrは、データを含む次のようにPythonの辞書エンドインタフェースにその署名をバイトまたはByteArrayのオブジェクトであってもよいです。

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

2.1最も簡単な例

json.loads最も基本的な方法は、このメソッドに渡されたSTRを含むJSONデータを使用することです。

>>> json.loads('{"a": 123}')
{'a': 123}

注意
Pythonで、strの値は一重引用符で配置することができますが、二重引用符で配置することができます。

>>> 'ABC' == "ABC"
True

したがって、辞書STRで定義されたタイプのキーと値は、単一または二重引用符は、正当と等価です。

>>> {"a": 'ABC'} == {'a': "ABC"}
True

しかし、JSON文字列データのみこうして治療のJSON文字列の内容json.loads方法は、文字列は二重引用符を使用する必要があり、二重引用符で囲むか、デコードエラーが発生することができます。

>>> json.loads("{'a': 123}")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Pythonは処理される文字列は二重引用符に含まれている場合は、JSONでの二重引用符はエスケープする必要があります。

>>> json.loads("{\"a\": 123}")
{'a': 123}

2.2バイトデータのByteArray

JSONとByteArrayのバイトのコンテンツデータについて、json.loads方法も治療することができます。

>>> json.loads('{"a": 123}'.encode('UTF-8'))
{'a': 123}
>>> json.loads(bytearray('{"a": 123}', 'UTF-8'))
{'a': 123}

2.3符号化フォーマット

2番目のパラメータは、符号化json.loadsない実用的な効果である。
Pythonの3 STR型は常にUTF-8エンコーディングを使用するため、Sパラメータは、型STR、自動的にUTF-8エンコーディングを使用するjson.loads方法である。そして、STR BOMは、バイトを開始できません。
Sパラメータは、バイトまたはByteArrayの、json.loads方法は自動的にUTF-8、UTF-16またはUTF-32エンコードされた判断した場合、デフォルトのSTRオブジェクトに変換され、UTF-8エンコーディングに従ってその後の処理のために。

2.4データ型変換

JSON型データは、マスター4種類を表すことができます

1.文字列
2.デジタル数字
3.ブールブールクラス
4ヌル値
二つの接合のデータ構造

1.オブジェクトオブジェクト
2.配列アンアレイ
デフォルト実装、次のようにJSONとPython対応関係との間のデータ変換:
ここに画像を挿入説明
以下の例実際のコンバージョン。

>>> json.loads("""
... {
... "obj": {
... "str": "ABC",
... "int": 123,
... "float": -321.89,
... "bool_true": true,
... "bool_false": false,
... "null": null,
... "array": [1, 2, 3]
... }
... }""")
{'obj': {'str': 'ABC', 'int': 123, 'float': -321.89, 'bool_true': True, 'bool_false': False, 'null': None, 'array': [1, 2, 3]}} 

データのデジタル数JSONタイプに対して、以下の点に留意すべきである:
実数型実精度1.JSONは、Pythonでfloat型の精度範囲を超えないように、そうでなければ、次の例の精度の損失があります。

>>> json.loads('3.141592653589793238462643383279')
3.141592653589793

、2.JSON標準は非数値NaNで、負の無限大と正の無限大のInfinity -Infinityが含まれていませんが、json.loads方法JSON文字列がフロート( 'ナン')にはNaN、無限大、-InfinityのPythonをデフォルト設定されますフロート(「INF」)とフロート(「 - INF」)は、本明細書JSONのNaN、無限大に、-Infinityは正しく入力し、次の例の場合を完了しなければならないと指摘しました。

>>> json.loads('{"inf": Infinity, "nan": NaN, "ninf": -Infinity}')
{'inf': inf, 'nan': nan, 'ninf': -inf}

2.5カスタム型オブジェクト変換JSON

JSONでjson.loadsのデフォルトのオブジェクトデータディクショナリ型は、パラメータがobject_hookを変更するために使用することができるから構成されるオブジェクト。
この関数の入力パラメータを受け入れる機能をobject_hookはJSON辞書オブジェクト内の変換対象データ、戻り値であります。次の例ではカスタムオブジェクトでした:

>>> class MyJSONObj:
... def __init__(self, x):
... self.x = x
...
>>> def my_json_obj_hook(data):
... print('obj_hook data: %s' % data)
... return MyJSONObj(data['x'])
...
>>> result = json.loads('{"x": 123}', object_hook=my_json_obj_hook)
obj_hook data: {'x': 123}
>>> type(result)
<class '__main__.MyJSONObj'>
>>> result.x
123

ネストされたJSONオブジェクトは、json.loadsオブジェクトツリー実施形態の深さ優先方式を横断するときに、それぞれの層は、ターゲットobject_hookにデータを渡す。構築PythonオブジェクトのJSONリーフノードを親ノードとなるように値は、以下の例の親ノードobject_hookメソッドに渡されます。

>>> class MyJSONObj:
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> def my_json_obj_hook(data):
... print('obj_hook data: %s' % data)
... return MyJSONObj(**data)
...
>>> result = json.loads('{"x": {"x": 11, "y": 12}, "y": {"x": 21, "y":22}}', object_hook=my_json_obj_hook)
obj_hook data: {'x': 11, 'y': 12}
obj_hook data: {'x': 21, 'y': 22}
obj_hook data: {'x': <__main__.MyJSONObj object at 0x10417ef28>, 'y': <__main__.MyJSONObj object at 0x10417ed68>} 

離れobject_hookパラメータは、このパラメータのパラメータobject_pairs_hookもjson.loads Pythonオブジェクトから構成されるタイプの方法を変更するために使用することができるされている。Object_hookこのパラメータは異なって、受信した入力データを通過させることを含む方法ではありません辞書が、リストのタプルを含んでいる。各タプルは2つの要素を有し、最初の要素はJSONデータキーで、2番目の要素はJSONオブジェクトとしてキーに対応する値であります

{
"a": 123,
"b": "ABC"
} 

入力データに対応
ここに画像を挿入説明
json.loadsメソッドを呼び出し、そして特定object_hook object_pairs_hook、object_pairs_hookオーバーライドobject_hookパラメータ。

2.6カスタム・デジタル変換型JSON

デフォルトの実装で、実際のJSONは、Pythonをfloat型に変換され、整数はintに変換または長いされている。同様にobject_hookは、我々はこれらの2つの方法の入力パラメータがありparse_floatとparse_intパラメータによってカスタマイズ変換ロジックを指定することができますJSON文字列は、本実施形態では実数または整数を表し、我々は実数numpy.float64、変換整数numpy.int64を変換します:

>>> def my_parse_float(f):
... print('%s(%s)' % (type(f), f))
... return numpy.float64(f)
...
>>> def my_parse_int(i):
... print('%s(%s)' % (type(i), i))
... return numpy.int64(i)
...
>>> result = json.loads('{"i": 123, "f": 321.45}', parse_float=my_parse_float, parse_int=my_parse_int)
<type 'str'>(123)
<type 'str'>(321.45)
>>> type(result['i'])
<type 'numpy.int64'>
>>> type(result['f'])
<type 'numpy.float64'> 

2.6.1カスタムのNaN、無限大の変換タイプと-Infinity

parse_floatこれらの値を受信して​​いないので、標準的なデータは、JSONのNaN、無限大と-Infinityをサポートしていないので、変換の値は、別のインターフェースparse_constantを使用する必要がある場合、これらのカスタム・オブジェクトを必要とする。次のように実施例でありますこれらのいくつかの値にnumpy.float64同じ型に変換:

>>> def my_parse_constant(data):
... print('%s(%s)' % (type(data), data))
... return numpy.float64(data)
...
>>> result = json.loads('{"inf": Infinity, "nan": NaN, "ninf": -Infinity}', parse_constant=my_parse_constant)
<type 'str'>(Infinity)
<type 'str'>(NaN)
<type 'str'>(-Infinity)
>>> result['inf']
inf
>>> type(result['inf'])
<type 'numpy.float64'> 

2.7トップ非目標値
JSON仕様に従って、JSONデータは一つの値だけではなく、完全なオブジェクトを含むことができる。この値は、文字列、数値、ブール値、ヌル、または配列とすることができる。これらに加えてJSON与えられた仕様の3種類ものNaN、無限大または-Infinityことがあります

>>> json.loads('"hello"')
'hello'
>>> json.loads('123')
123
>>> json.loads('123.34')
123.34
>>> json.loads('true')
True
>>> json.loads('false')
False
>>> print(json.loads('null'))
None
>>> json.loads('[1, 2, 3]')
[1, 2, 3] 

2.8重複キー

同じ階層内のJSONオブジェクト、名前が重複したキーが表示されますされませんが、何の仕様は、このような状況にJSONにjson.loadsにおける標準治療を与えられていない、JSONデータが重複キーがある場合、キーは後になります表紙:

>>> json.loads('{"a": 123, "b": "ABC", "a": 321}')
{'a': 321, 'b': 'ABC'}

2.9 JSONデータファイルを処理します

JSONデータがファイルに格納されている場合と、json.load方法は、ファイルからデータを読み取るために使用され、Pythonオブジェクトに変換することができる。最初のパラメータの方法は、ポインタjson.load JSONデータファイルタイプであります。オブジェクト
/tmp/data.jsonファイルは、以下が含まれているような:

{
"a": 123,
"b": "ABC"
} 

コードは、変換データファイルを読み込み、JSON、次の例で使用することができます。

>>> with open('/tmp/data.json') as jf:
... json.load(jf)
...
{u'a': 123, u'b': u'ABC'} 

オブジェクトのファイルタイプに加えて、限りオブジェクトファイルを達成するための読み出し方法として、FPは、io.StringIOの実施例として、パラメータとして使用することができます。

>>> sio = io.StringIO('{"a": 123}')
>>> json.load(sio)
{'a': 123}

意味と上記およびその他のパラメータjson.load json.loads同じ方法の使用は、ここではそれらを繰り返すません。
私たちのお勧めのpython学習サイトをプログラムで学ぶことです何歳見て、!基本的なPythonスクリプト、爬虫類、ジャンゴ、データマイニング、技術をプログラミング、仕事の経験だけでなく、小型のpythonパートナーのシニア入念な研究から戦闘にゼロベースの情報のプロジェクトを仕上げ!時限プログラマPythonは日常の技術を説明している方法は、学習と細部への注意を払う必要性へのいくつかを共有します

図3は、JSONを生成し、

この方法は、ジョンインターフェイス以下その完全シグネチャを表すPythonオブジェクトデータの文字列に変換することができるjson.dumps。

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.dumps({'a': 123, 'b': 'ABC'})
'{"a": 123, "b": "ABC"}'

3.1符号化フォーマット

ensure_ascii生成されたエンコードJSON文字列を制御するためのjson.dumpsパラメータ。デフォルト値は、ノートのすべてが非ASCIIエスケープされ、この時、真である。自動的にエスケープしたくない場合は、元のコードを維持します、制限UTF-8次の例で:

>>> json.dumps({'数字': 123, '字符': '一二三'})
'{"\\u6570\\u5b57": 123, "\\u5b57\\u7b26": "\\u4e00\\u4e8c\\u4e09"}'
>>> json.dumps({'数字': 123, '字符': '一二三'}, ensure_ascii=False)
'{"数字": 123, "字符": "一二三"}'

3.2データ型変換

デフォルトの実装では、Pythonは処理できるオブジェクトをjson.dumps、およびすべての属性値は、型辞書、リスト、タプル、STR、でなければなりませんフロート次のようにデータ変換関係のこれらのタイプのintまたはJSON:ここに画像を挿入説明
実際の変換を次の例:

>>> json.dumps(
... {
... 'str': 'ABC',
... 'int': 123,
... 'float': 321.45,
... 'bool_true': True,
... 'bool_false': False,
... 'none': None,
... 'list': [1, 2, 3],
... 'tuple': [12, 34]
... }
... )
'{"str": "ABC", "int": 123, "float": 321.45, "bool_true": true, "bool_flase": false, "none": null, "list": [1, 2, 3], "tuple": [12, 34]}'

JSON標準仕様がNaN、無限大と-Infinityをサポートしていませんが、デフォルトjson.dumps実装は(「ナン」)をフロートしますが、フロート(「INF」)とフロート(「 - INF」)は、定数はNaN、無限大に変換され、 。-Infinityと、次の例:

>>> json.dumps(
... {
... 'nan': float('nan'),
... 'inf': float('inf'),
... '-inf': float('-inf')
... }
... )
'{"nan": NaN, "inf": Infinity, "-inf": -Infinity}'

由于这些常量可能会导致生成的JSON字符串不能被其他的JSON实现处理, 为了防止这种情况出现, 可以将json.dumps的allow_nan参数设置为True. 此时, 当处理的Python对象中出现这些值时, json.dumps方法会抛出异常.

3.3 循环引用

json.dumps方法会检查Python对象中是否有循环引用, 如果发现了循环引用, 就会抛出异常. 如下例所示:

>>> circular_obj = {}
>>> circular_obj['self'] = circular_obj
>>> circular_obj
{'self': {...}}
>>> json.dumps(circular_obj)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
ValueError: Circular reference detected

如果不希望json.dumps方法检查循环引用, 可以将参数check_circular设置为False. 但如果此时Python对象中有循环引用, 有可能发生递归嵌套过深的错误或者其他错误, 这么做是比较危险的. 如下例所示:

>>> json.dumps(circular_obj, check_circular=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object

3.4 JSON字符串输出格式

json.dumps方法的indent参数可以用来控制JSON字符串的换行和缩进效果.
indent参数默认值为None. 此时, JSON字符串不会有换行和缩进效果. 如下示:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}))
{"a": 123, "b": {"x": 321, "y": "ABC"}} 

当indent为0或者负数时, JSON字符会包含换行:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=-1))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}
>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=0))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
} 

而当indent为正整数时, 除了换行, JSON还会以指定数量的空格为单位在对象层次间进行缩进:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=2))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}

indent还可以是str, 此时, JSON会以str内容为单位进行缩进, 比如制表符\t:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent='\t'))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
} 

json.dumps的另外一个参数separators可以用来设置输出的分隔符. 这个参数的值应当是一个有两个元素的tuple. 其第一个值为成员间的分隔符, 第二个值为键值之间的分隔符. 其默认值也会随上文中的indent参数影响. 当indent为None时, separators的默认值为(’, ‘, ‘: ‘), 即分隔符后都有一个空格. 当indent不为None时, 其默认值则为(’,’, ‘:’), 即只有键值间分隔符后会有一个空格, 而元素间分隔符则不带空格, 因为此时会有换行.
separators参数的一种可能的使用场景是希望移除所有的非必要格式字符, 以此来减小JSON字符串的大小. 此时可以将separator设置为(’,’, ‘;’), 并不设置indent参数, 或者将其显式设置为None:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=None, separators=(',', ':')))
{"a":123,"b":{"x":321,"y":"ABC"}}

3.5 转换自定义Python对象
json.dumps的默认实现只能转换Dictionary类型的对象. 如果想要转换自定义对象, 需要使用default参数. 这个参数接收一个函数, 这个函数的参数是一个要转换的Python对象, 返回值是能够表示这个Python对象的Dictionary对象. default函数会从对象引用树的顶层开始, 逐层遍历整个对象引用树. 因此, 不用自己实现对象树的遍历逻辑, 只需要处理当前层次的对象. 如下例所示:

>>> class MyClass:
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> def my_default(o):
... if isinstance(o, MyClass):
... print('%s.y: %s' % (type(o), o.y))
... return {'x': o.x, 'y': o.y}
... print(o)
... return o
...
>>> obj = MyClass(x=MyClass(x=1, y=2), y=11)
>>> json.dumps(obj, default=my_default)
<class '__main__.MyClass'>.y: 11
<class '__main__.MyClass'>.y: 2
'{"x": {"x": 1, "y": 2}, "y": 11}'

3.6 非字符串类型键名

在Python中, 只是可哈希(hashable)的对象和数据都可以做为Dictionary对象的键, 而JSON规范中则只能使用字符串做为键名. 所以在json.dumps的实现中, 对这个规则进行了检查, 不过键名允许的范围有所扩大, str, int, float, bool和None类型的数据都可以做为键名. 不过当键名非str的情况时, 键名会转换为对应的str值. 如下例:

>>> json.dumps(
... {
... 'str': 'str',
... 123: 123,
... 321.54: 321.54,
... True: True,
... False: False,
... None: None
... }
... )
'{"str": "str", "123": 123, "321.54": 321.54, "true": true, "false": false, "null": null}'

而当出现其他类型的键名时, 默认出抛出异常:

>>> json.dumps({(1,2): 123})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
TypeError: keys must be a string 

json.dumps的skipkeys参数可以改变这个行为. 当将skipkeys设置为True时, 遇到非法的键名类型, 不会抛出异常, 而是跳过这个键名:

>>> json.dumps({(1,2): 123}, skipkeys=True)
'{}'

3.7 生成JSON文件
当需要将生成的JSON数据保存到文件时, 可以使用json.dump方法. 这个方法比json.dumps多了一个参数fp, 这个参数就是用来保存JSON数据的文件对象. 比如, 下例中的代码

>>> with open('/tmp/data.json', mode='a') as jf:
... json.dump({'a': 123}, jf)
...

就会将JSON数据写入到/tmp/data.json文件里. 代码执行完后, 文件内容为

{"a": 123} 
json.dump方法也可以接受其他类文件对象:
>>> sio = io.StringIO()
>>> json.dump({'a': 123}, sio)
>>> sio.getvalue()
'{"a": 123}'

json.dump的其他参数和json.dumps的用法相同, 这里不再赘述.

4 JSON解码和编码类实现

json.loads, json.load, json.dumps和json.dump这四个方法是通过json.JSONDecoder和json.JSONEncoder这两个类来完成各自的任务的. 所以也可以直接使用这两个类来完成前文描述的功能:

>>> json.JSONDecoder().decode('{"a": 123}')
{'a': 123}
>>> json.JSONEncoder().encode({'a': 123})
'{"a": 123}'

json.loads, json.load, json.dumps和json.dump这个四个方法的参数主要都是传递给了json.JSONDecoder和json.JSONEncoder的构造方法, 所以使用这些方法可以满足绝大部分需求. 当需要自定义json.JSONDecoder和json.JSONEncoder子类的时候, 只需要将子类传递给cls参数. 同时, 这些方法都有**kw参数. 当自定义实现类的构造函数需要标准参数列表之外的新参数时, 这个参数就会将新参数传递给实现类的构造方法.

这个是我们的学习基地,欢迎大家加入学习了,
ここに画像を挿入説明

发布了21 篇原创文章 · 获赞 9 · 访问量 2万+

おすすめ

転載: blog.csdn.net/haoxun06/article/details/104435319