python json详解

转自:https://blog.csdn.net/bitcarmanlee/article/details/52728586

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-8

import json

class Person(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

person = Person("James",18)
print (json.dumps(person))

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

扫描二维码关注公众号,回复: 1691068 查看本文章
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-8

import json

class Person(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

def 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-8

import json

class Person(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

def 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-8

import json

class Person(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

def 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对象的目的!


猜你喜欢

转载自blog.csdn.net/u012111923/article/details/80705262