Python类对象的JSON序列化处理

不同的编程语言有不同的数据类型; 比如说:
Python的数据类型有(dict、list、string、int、float、long、bool、None)
Java的数据类型有(bool、char、byte、short、int、long、float、double)
C的数据类型有(bit、bool、char、int、short、long、unsigned、double、float)
Tcl的数据类型(int、bool、float、string)
Ruby的数据类型(Number、String、Ranges、Symbols、true、false、Array、Hash)
...
他们的共同特点是,都有字符串类型!
所以要实现不同的编程语言之间对象的传递,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。

JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便.


JSON类型            Python类型
{}                  dict
[]                  list
"string"            str
1234.56             int或float
true                True
false               False
null                None


Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。

json.dumps()         将Python中的对象转换为JSON中的字符串对象
json.loads()         将JSON中的字符串对象转换为Python中的对象


我们先看看如何把Python对象变成一个JSON,转换后的JSON对象,最后都是字符串型。

Python类对象的JSON序列化处理

但是如果是类对象,是不是可以可以直接用json.dumps(obj)来处理呢?比如像下面一个简单类:

Python类对象的JSON序列化处理

运行之后会报下面TypeError: 说该对象非JSON的序列化对象

Python类对象的JSON序列化处理

错误的原因是Man对象不是一个可序列化为JSON的对象。如果连class的实例对象都无法序列化为JSON,这肯定不合理!我们仔细看看dumps()方法的参数列表,可以发现,除了第一个必须的obj参数外,dumps()方法还提供了一大堆的可选参数:

>>> help(json.dumps)
Help on function dumps in module 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)

这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把Man类实例序列化为JSON,是因为默认情况下,dumps()方法不知道如何将Man实例变为一个JSON的{}对象。

可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Man专门写一个转换函数,再把函数传进去即可:

Python类对象的JSON序列化处理

Python类对象的JSON序列化处理

或者通过一种简单的方式,用lambda方式来转换任意一个类对象为JSON形式:

Python类对象的JSON序列化处理

Python类对象的JSON序列化处理

lambda obj: obj.__dict__          会将任意的对象,转换成字典的方式

sort_keys=True                    会按照字典中的键来按照ASCII方式来排序

indent=4                          会按照键值对以间隔4来直观的显示

同样的道理,如果要将JSON对象反序列化,也可以写个函数来转换:

son.loads(json_str, object_hook=handle)

Python类对象的JSON序列化处理

Python类对象的JSON序列化处理

从上面的操作,基本上就完成了从JSON字符串方式到类对象的处理.

json.dumps()函数的详细说明

>>> help(json.dumps)
Help on function dumps in module 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)


#  函数作用:       将Python的对象转变成JSON对象

#  skipkeys:       如果为True的话,则只能是字典对象,否则会TypeError错误, 默认False

#  ensure_ascii:   确定是否为ASCII编码

#  check_circular: 循环类型检查,如果为True的话

#  allow_nan:      确定是否为允许的值

#  indent:         会以美观的方式来打印,呈现

#  separators:     对象分隔符,默认为, 

#  encoding:       编码方式,默认为utf-8     

#  sort_keys:      如果是字典对象,选择True的话,会按照键的ASCII码来排序    


最后总结】      

Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。


json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性