Python学习—JSON序列化处理

之前学习了序列化的一种方法——pickle序列化。
其核心是通过pickle.dumps()将对象序列化为str,之后再将这个str写入文件。打开刚才的文件,我们发现,刚才辛苦序列化半天的东西,竟然完全是一些莫名字符的堆积——Python保存的对象内部信息。因此当需要将对象从磁盘读取到内存时,首先要把内容读成str,再通过pickle.loads()反序列化出对象。

但是Pickle的问题和所有其他编程语言特有的序列化问题一样,它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据。

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。所以也就引出了json这个强大的序列化方法。

这里写图片描述

  1. 实现将一个python类型转换为json对象:
import json
# python字典类型转换为json对象
d = dict(name='zhuzhuzhu', age='20', score='99')
x = json.dumps(d)
print x

OUTPUT : {“age”: “20”, “score”: “99”, “name”: “zhuzhuzhu”}

  1. 实现将json对象再转换为python类型
y = json.loads(x)
print y

OUTPUT : {u’age’: u’20’, u’score’: u’99’, u’name’: u’zhuzhuzhu’}

注意
反序列化得到的所有字符串对象默认都是unicode而不是str。由于JSON标准规定JSON编码是UTF-8,所以我们总是能正确地在Python的str或unicode与JSON的字符串之间转换。

  1. 如果需要处理的不是字符串而是文件,可以使用json.dump()和json.load()进行编码和解码json数据。
# 写入 JSON 数据
with open('data.json', 'w') as f:
    json.dump(data, f)

# 读取数据
with open('data.json', 'r') as f:
    data = json.load(f)
  1. json可以对一个字典表示的对象进行序列化,但是很多时候,我们更倾向于用class——类来表示对象。
class Animal(object):
    def __init__(self, species, color, weight):
        self.species = species
        self.color = color
        self.weight = weight


dog = Animal('Dog', 'red', '50')
print json.dumps(dog)

运行之后发现报错,错误原因是Animal对象不是一个可序列化为JSON的对象。
通过查资料可得,dumps()的可选参数default可以把任意一个对象变成一个可序列为JSON的对象。
因此,我们专门为类Animal写一个转换函数,将其作为参数default的值传进去。

class Animal(object):
    def __init__(self, species, color, weight):
        self.species = species
        self.color = color
        self.weight = weight


def animal2dic(animal):
    return{
        'species': animal.species,
        'color': animal.color,
        'weight': animal.weight
    }


dog = Animal('Dog', 'red', '50')
print json.dumps(dog, default=animal2dic)

OUTPUT : {“color”: “red”, “species”: “Dog”, “weight”: “50”}

另外,可以将任意的class的实例变为dict,因为通常class的实例都有一个dict属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了slots的class。

print json.dumps(s, default=lambda obj: obj.__dict__)

同样,我们要将一个json对象反序列化为类的对象实例,首先用loads()方法转换出一个dict对象,然后,定义一个将dict转换为类的函数,将其作为object_hook参数的值传入。

def dict2animal(dic):
    return Animal(dic['species'], dic['color'], dic['weight'])


json_str = '{"species": "Dog", "color": "red", "weight": 50}'
print json.loads(json_str, object_hook=dict2animal)

OUTPUT : <main.Animal object at 0x000000000555E8D0>
打印出来的是反序列化的Animal实例对象。

猜你喜欢

转载自blog.csdn.net/in_nocence/article/details/80142978