python json详解

来源:互联网 发布:画图软件图标大全 编辑:程序博客网 时间:2024/06/06 10:43

1.json是什么

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。json最大的优势就是独立于编程语言, 易于人阅读和编写,同时也易于机器解析和生成。所以,如果我们需要在不同的编程语言之间传递对象,或者需要在网络世界中传输数据,我们都可以将数据序列化为json格式。当将其序列化为json格式以后,可以方便地被所有编程语言读取与解析,也可以方便地被存储在磁盘中或者用于网络传输。正因为有这些优点,json在实际中使用非常广泛。

JSON构建于两种结构:
1.“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
2.值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

2.python数据类型与json数据类型的映射关系

Python类型 JSON类型
dict {}
list []
str(unicode) string
int(float,long) number
True(False) true(false)
None null

3.python中json模块的简单用法

python中内置的json模块就可以完成从python对象到json格式数据的转换。
先来看看怎么把一个python对象变为一个json串:

>>> import json>>> dic = dict(name='James',age=18)>>> dic_to_str = json.dumps(dic)>>> dic_to_str'{"age": 18, "name": "James"}'>>> type(dic_to_str)<type 'str'>

通过dumps方法,就把一个dict变为了一个json串,返回的是一个str对象。dumps方法相当于一个encoding过程,是对简单数据类型的编码。也可以理解是对python对象的一个序列化的过程。

接下来看看如何把一个json串变为一个python对象:

>>> str_to_dic = json.loads(dic_to_str)>>> str_to_dic{u'age': 18, u'name': u'James'}>>> type(str_to_dic)<type 'dict'>

同理通过loads方法,将一个json串,变为了一个dict对象,返回的是一个dict。loads方法相当于是一个decoding过程,是对字符串的一个解码。当然也可以理解为是对python对象的反序列化!

4.将自己的类转成json串

前面我们看了怎样将python中的内置dict对象转化为json串的过程。在很多时候,我们希望将自己定义的类也转化为json串。比如我们自己定义了person类,并且希望将其序列化为json串:

#!/usr/bin/env python#coding:utf-8import jsonclass Person(object):    def __init__(self,name,age):        self.name = name        self.age = ageperson = Person("James",18)print (json.dumps(person))

将上面的代码run起来以后,会有以下错误:

Traceback (most recent call last):  File "./person.py", line 13, in <module>    print (json.dumps(person))  File "/Users/lei.wang/anaconda/lib/python2.7/json/__init__.py", line 244, in dumps    return _default_encoder.encode(obj)  File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 207, in encode    chunks = self.iterencode(o, _one_shot=True)  File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 270, in iterencode    return _iterencode(o, 0)  File "/Users/lei.wang/anaconda/lib/python2.7/json/encoder.py", line 184, in default    raise TypeError(repr(o) + " is not JSON serializable")TypeError: <__main__.Person object at 0x101a00090> is not JSON serializable

很明显可以看出,是我们无法将person对象序列化!
我们再仔细观察一下dumps()方法:

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)Serialize obj to a JSON formatted str using this conversion table. If ensure_ascii is false, the result may contain non-ASCII characters and the return value may be a unicode instance.

参数default选项就是将一个对象变为一个可序列化的Json对象。前面的Person类就是因为没有指定default选项,所以无法序列化。现在我们为Person类写一个专门的序列化方法:

!/usr/bin/env python#coding:utf-8import jsonclass Person(object):    def __init__(self,name,age):        self.name = name        self.age = agedef person_to_dict(person):    return {        'name': person.name,        'age':  person.age            }person = Person("James",18)print json.dumps(person,default = person_to_dict)

将代码运行起来:

{"age": 18, "name": "James"}

上面这么做的目的,就是通过person_to_dict方法,将person对象转化为dict对象,然后通过将default选项设置为person_to_dict,就可以使用dumps方法将person对象序列化为json对象了!

当然,如果我们想偷点懒,也是可以的。可以不写person_to_dict方法,直接调用person类的dict方法:

!/usr/bin/env python#coding:utf-8import jsonclass Person(object):    def __init__(self,name,age):        self.name = name        self.age = agedef person_to_dict(person):    return {        'name': person.name,        'age':  person.age            }person = Person("James",18)print json.dumps(person,default = lambda obj:obj.__dict__)print json.dumps(person,default = person_to_dict)

让代码run起来:

{"age": 18, "name": "James"}{"age": 18, "name": "James"}

由此可见,print两行代码的效果是一致的!

同样的道理,既然能将自己定义的类转化为json串,同理也能将json串变为类。我们先看看loads方法:

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])Deserialize s (a str or unicode instance containing a JSON document) to a Python object using this conversion table.object_hook is an optional function that will be called with the result of any object literal decoded (a dict). The return value of object_hook will be used instead of the dict. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting).

仿照上面的思路:

#!/usr/bin/env python#coding:utf-8import jsonclass Person(object):    def __init__(self,name,age):        self.name = name        self.age = agedef dic_to_person(dic):    return Person(dic['name'],dic['age'])json_person = '{"name":"James","age":18}'print json.loads(json_person,object_hook = dic_to_person)

让代码run起来:

<__main__.Person object at 0x1022071d0>

由此可见,我们通过loads方法,达到了将json字符串反序列化为Person对象的目的!

0 0
原创粉丝点击