简介
Json模块主要用来进行Python对象的序列化和反序列化。
该模块中常用的方法有以下四个:
-
json.dump
将Python对象序列化为Json格式的数据流并写入文件类型的对象中 -
json.dumps
将Python对象序列化为Json格式的字符串 -
json.load
从文件类型的对象中读取Json格式的数据并反序列化成Python对象 -
json.loads
将包含Json格式数据的字符串反序列化成Python对象
进行序列化时,Python类型与Json类型的转换关系如下表所示:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | true |
False | false |
None | null |
进行反序列化时,Json类型与Python类型的转换关系如下:
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number(int) | int |
number(real) | float |
true | True |
false | False |
null | None |
常用方法详解
由于
json.dump
和
json.dumps
这两个方法、的作用与使用方法类似,故只对其中之一详细介绍。
同样地,
json.load
和
json.loads
这两个方法的作用与使用方法类似,故也只对其中之一详细介绍。
json.dumps
该方法包含一个位置参数和多个仅限关键字参数,分别如下所示:
-
obj
要序列化的Python对象 -
skipkeys=False
是否跳过要序列化的对象中字典元素的key不是基本类型的数据;
如果为True,则跳过,如果为False,将抛出TypeError异常。>> > emp_info = { 'name' : 'bob' , b 'age' : 24 } # 包含key为bytes类型的元素 >> > json . dumps ( emp_info ) # skipkeys参数为默认值False Traceback ( most recent call last ) : File "
" , line 1 , in < module > File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py" , line 231 , in dumps return _default_encoder . encode ( obj ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 199 , in encode chunks = self . iterencode ( o , _one_shot = True ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 257 , in iterencode return _iterencode ( o , 0 ) TypeError : keys must be str , int , float , bool or None , not bytes >> > json . dumps ( emp_info , skipkeys = True ) # skipkeys参数设置为True时则可成功序列化 '{"name": "bob"}' -
ensure_ascii=True
是否将要序列化的对象中的字符串中的非ascii字符进行转义。
如果该参数为True,则将字符串中的非ascii字符转义成unicode字符串,否则,将不会进行转义。>> > message = '我爱Python3' >> > json . dumps ( message ) # ensure_ascii参数默认值为True,将会把非ascii字符转移成unicode字符串 '"\\u6211\\u7231Python3"' >> > json . dumps ( message , ensure_ascii = False ) # ensure_ascii参数设置为False时,不会进行转义 '"我爱Python3"'
-
check_circular=True
是否进行容器类型的循环引用检查。
如果该参数设置为False,则不进行检查,但是可能会引发OverflowError或更严重的情况。
如果该参数设置为True,则将进行容器类型的循环引用检查,并在发现循环引用时抛出异常。emp_dict = { 'id' : 1 , 'dept' : 'sales' } >> > emp_dict [ 'info' ] = emp_dict # 字典中包含循环引用 >> > json . dumps ( emp_dict ) # 默认进行循环引用的检查,将引发ValueError异常 Traceback ( most recent call last ) : File "
" , line 1 , in < module > File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py" , line 231 , in dumps return _default_encoder . encode ( obj ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 199 , in encode chunks = self . iterencode ( o , _one_shot = True ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 257 , in iterencode return _iterencode ( o , 0 ) ValueError : Circular reference detected >> > json . dumps ( emp_dict , check_circular = False ) # 设置为不进行循环引用的检查,但是在编码Json对象时仍然引发了异常 Traceback ( most recent call last ) : File "" , line 1 , in < module > File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py" , line 238 , in dumps ** kw ) . encode ( obj ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 199 , in encode chunks = self . iterencode ( o , _one_shot = True ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 257 , in iterencode return _iterencode ( o , 0 ) RecursionError : maximum recursion depth exceeded while encoding a JSON object -
allow_nan=True
是否允许序列化超出范围的float类型的值(如float(‘inf’)、float(’-inf’)、float(‘nan’))。
如果该参数设置为True,则上面列出的那些值将依次使用JavaScript中等价的值(Infinity、-Infinity、NaN)来进 行替代;
如果该参数设置为False,并且要序列化的对象中出现了那些超出范围的值,则将引发ValueError异常。>> > num_list = [ 2 , 5 , float ( 'inf' ) , float ( '-inf' ) , float ( 'nan' ) ] >> > json . dumps ( num_list ) # allow_nan的值默认为True,列表中后三个值将被替换为js中等价的值 '[2, 5, Infinity, -Infinity, NaN]' >> > json . dumps ( num_list , allow_nan = False ) # allow_nan设置为False,引发ValueError异常 Traceback ( most recent call last ) : File "
" , line 1 , in < module > File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py" , line 238 , in dumps ** kw ) . encode ( obj ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 199 , in encode chunks = self . iterencode ( o , _one_shot = True ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 257 , in iterencode return _iterencode ( o , 0 ) ValueError : Out of range float values are not JSON compliant -
indent=None
是否在数组元素和对象成员前增加缩进以便使格式更加美观。
如果该参数设置为大于等于1的整数,则添加换行符和对应数量的空格表示缩进,如果设置为0,则表示只添加换行符,如果设置为None,则表示无缩进。>> > response = { 'status' : 'success' , 'code' : 200 , 'data' : [ '002' , 'json' , 5000 ] } >> > print ( json . dumps ( response ) ) # 默认值None,不缩进 { "status" : "success" , "code" : 200 , "data" : [ "002" , "json" , 5000 ] } >> > print ( json . dumps ( response , indent = 0 ) ) # 设置为0,则只添加换行 { "status" : "success" , "code" : 200 , "data" : [ "002" , "json" , 5000 ] } >> > print ( json . dumps ( response , indent = 4 ) ) # 设置为4,添加换行和缩进 { "status" : "success" , "code" : 200 , "data" : [ "002" , "json" , 5000 ] }
-
separators=None
设置Json中各项之间、对象的键和值之间的分隔符;
该参数必须是一个2元组,元组第一个元素表示Json数据中各项之间的分隔符,元组的第二个元素表示Json对象的键和值之间的分隔符。默认的分隔符为(’,’, ‘:’)>> > response = { 'status' : 'success' , 'code' : 200 , 'data' : [ '002' , 'json' , 5000 ] } >> > print ( json . dumps ( response , separators = ( ';' , '!' ) ) ) >> > print ( json . dumps ( response , indent = 4 , separators = ( ';' , '!' ) ) ) { "status" ! "success" ; "code" ! 200 ; "data" ! [ "002" ; "json" ; 5000 ] }
-
default=None
指定一个函数,用来将不可进行序列化的Python对象转化为可序列化的Python对象>> > json . dumps ( b 'hello world' ) Traceback ( most recent call last ) : File "
" , line 1 , in < module > File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py" , line 231 , in dumps return _default_encoder . encode ( obj ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 199 , in encode chunks = self . iterencode ( o , _one_shot = True ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 257 , in iterencode return _iterencode ( o , 0 ) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py" , line 179 , in default raise TypeError ( f 'Object of type {o.__class__.__name__} ' TypeError : Object of type bytes is not JSON serializable >> > json . dumps ( b 'hello world' , default = list ) '[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]' >> > json . dumps ( b 'hello world' , default = str ) '"b\'hello world\'"' -
sort_keys=False
是否要将对象中字典元素按照key进行排序。
默认为False,即不进行排序,若指定为True,则会进行排序。>> > emp_info = { 'name' : 'bob' , 'age' : 23 , 'dept' : 'sales' , 'gender' : 'male' } >> > print ( json . dumps ( emp_info , indent = 4 ) ) # 不按照key排序 { "name" : "bob" , "age" : 23 , "dept" : "sales" , "gender" : "male" } >> > print ( json . dumps ( emp_info , indent = 4 , sort_keys = True ) ) # 按照key进行排序 { "age" : 23 , "dept" : "sales" , "gender" : "male" , "name" : "bob" }
-
cls=None
指定一个定制的JSONEncoder的子类(例如,重写了.default()方法用来序列化附加的类型),指定该参数时请使用cls关键字参数。如果未指定该参数,则将使用默认的JSONEncoder。>> > class IteratorEncoder ( json . encoder . JSONEncoder ) : . . . def default ( self , o ) : . . . try : . . . iterable = iter ( o ) . . . except TypeError : . . . pass . . . else : . . . return list ( iterable ) . . . return super ( ) . default ( self , o ) . . . >> > def get_nums ( n ) : . . . if not isinstance ( n , int ) : . . . raise TypeError ( 'Expected int object' ) . . . while n > 0 : . . . yield n . . . n -= 1 . . . >> > print ( json . dumps ( get_nums ( 10 ) , indent = 4 , cls = IteratorEncoder ) ) [ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ]
json.dump
下面演示下该方法的简单用法:
>>
>
response
=
{
'status'
:
'success'
,
'code'
:
200
,
'data'
:
{
'username'
:
'bob'
,
'user_level'
:
6
,
'nickname'
:
'playboy'
}
}
>>
>
with
open
(
'res.json'
,
'w'
,
encoding
=
'utf-8'
)
as
f
:
.
.
.
json
.
dump
(
response
,
f
,
indent
=
4
)
.
.
.
>>
>
os
.
system
(
'cat res.json'
)
{
"status"
:
"success"
,
"code"
:
200
,
"data"
:
{
"username"
:
"bob"
,
"user_level"
:
6
,
"nickname"
:
"playboy"
}
}
0
>>
>
json.loads
该方法包含一个位置参数和多个仅限关键字参数,分别如下所示:
-
s
-
encoding=None
该参数已弃用,将会被忽略 -
cls=None
指定一个定制的JsonDecoder子类,以便实现特定的反序列化需求; -
object_hook=None
接受一个可调用对象,用于处理解码后生成的Python对象中dict类型的值。
注意,这个处理过程是递归进行的,即返回的Python对象内部所有的字典结构都将被这个方法处理>> > emp_info = { 'name' : 'bob' , 'age' : 25 , 'gender' : 'Male' } >> > def obj_hook ( _dict ) : . . . return list ( _dict . items ( ) ) . . . >> > json . loads ( json . dumps ( emp_info ) ) { 'name' : 'bob' , 'age' : 25 , 'gender' : 'Male' } >> > json . loads ( json . dumps ( emp_info ) , object_hook = obj_hook ) [ ( 'name' , 'bob' ) , ( 'age' , 25 ) , ( 'gender' , 'Male' ) ] >> > emp_list = [ 25 , emp_info ] >> > emp_list [ 25 , { 'name' : 'bob' , 'age' : 25 , 'gender' : 'Male' } ] >> > json . loads ( json . dumps ( emp_list ) , object_hook = obj_hook ) [ 25 , [ ( 'name' , 'bob' ) , ( 'age' , 25 ) , ( 'gender' , 'Male' ) ] ] >> > emp_d = [ 25 , { 'name' : 'bob' , 'age' : 25 , 'gender' : 'Male' , 'emp_info' : { 'count' : 9 , 'total_salary' : 120000 } } ] >> > json . loads ( json . dumps ( emp_d ) , object_hook = obj_hook ) [ 25 , [ ( 'name' , 'bob' ) , ( 'age' , 25 ) , ( 'gender' , 'Male' ) , ( 'emp_info' , [ ( 'count' , 9 ) , ( 'total_salary' , 120000 ) ] ) ] ]
-
parse_float=None
用于处理解码后的Python对象中的float类型的值。>> > json . loads ( '[23.5, 43.32, 5.934]' , parse_float = lambda x : int ( x ) ) # 将解码后的所有的float类型的值转成int类型 [ 23 , 43 , 5 ] >> > json . loads ( '[23.5, 43.32, 5.934]' , parse_float = lambda x : str ( x ) ) # 将解码后的所有的float类型的值转成str类型 [ '23.5' , '43.32' , '5.934' ]
-
parse_constant=None
接受一个可调用对象,用于解码时对Infinity、-Infinity、NaN或其他非法的Json数值的处理。>> > def parse_cons ( cons ) : . . . if cons == 'Infinity' : . . . return 100000000 . . . elif cons == '-Infinity' : . . . return - 100000000 . . . elif cons == 'NaN' : . . . return None . . . else : . . . raise Value ( f "Can't convert this value {cons}" ) . . . >> > json . loads ( '[Infinity, -Infinity, NaN]' , parse_constant = parse_cons ) [ 100000000 , - 100000000 , None ]
-
object_parse_hook=None
如果指定了该参数并且设置为一个可调用对象,那么Json对象将被解码成一个元素为二元组的列表,二元组的两个元素分别为Json对象中的键值对的键和值,并且列表中元素的顺序与Json对象中键值对的顺序一致。
>>
>
emp_info
=
{
'name'
:
'bob'
,
'age'
:
23
,
'dept'
:
'sales'
,
'gender'
:
'male'
}
>>
>
json
.
loads
(
json
.
dumps
(
emp_info
)
,
object_pairs_hook
=
str
)
"[('name', 'bob'), ('age', 23), ('dept', 'sales'), ('gender', 'male')]"
>>
>
from
collections
import
OrderedDict
>>
>
json
.
loads
(
json
.
dumps
(
emp_info
)
,
object_pairs_hook
=
OrderedDict
)
OrderedDict
(
[
(
'name'
,
'bob'
)
,
(
'age'
,
23
)
,
(
'dept'
,
'sales'
)
,
(
'gender'
,
'male'
)
]
)
json.load
下面演示下该方法的简单用法:
>>
>
with
open
(
'res.json'
,
encoding
=
'utf-8'
)
as
f
:
.
.
.
json
.
load
(
f
)
.
.
.
{
'status'
:
'success'
,
'code'
:
200
,
'data'
:
{
'username'
:
'bob'
,
'user_level'
:
6
,
'nickname'
:
'playboy'
}
}
转载:https://blog.csdn.net/swinfans/article/details/86501555