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中的对象
但是如果是类对象,是不是可以可以直接用json.dumps(obj)来处理呢?比如像下面一个简单类:
运行之后会报下面TypeError: 说该对象非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
专门写一个转换函数,再把函数传进去即可:
或者通过一种简单的方式,用lambda方式来转换任意一个类对象为JSON形式:
lambda obj: obj.__dict__ 会将任意的对象,转换成字典的方式
sort_keys=True 会按照字典中的键来按照ASCII方式来排序
indent=4 会按照键值对以间隔4来直观的显示
同样的道理,如果要将JSON对象反序列化,也可以写个函数来转换:
son.loads(json_str, object_hook=handle)
从上面的操作,基本上就完成了从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()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性