Python3 - 序列化

1 Pickle模块

  • 通过pickle.dumps()序列化,生成一个bytes对象。

    1
    2
    3
    4
    5
    6
    import pickle

    d = dict(name = "Bob", age = 20, score = 90)

    # b'\x80\x03}q\x00(X\x05\x00\x00\x00scoreq\x01KZX\x04\x00\x00\x00nameq\x02X\x03\x00\x00\x00Bobq\x03X\x03\x00\x00\x00ageq\x04K\x14u.'
    print(pickle.dumps(d))

  • 也可通过pickle.dump()直接将内存中的对象序列化后存入文件中。如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import pickle

    d = dict(name = "Bob", age = 20, score = 90)

    f = open("dump.txt", "wb")

    pickle.dump(d, f)

    f.close()

  • 通过pickle.loads()将一个从文件读入到内存的bytes,反序列化成一个对象。或者直接通过pickle.load()将一个文件中的内容读入到内存,然后直接反序列化成一个对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import pickle

    file = open("dump.txt", "rb")

    d = pickle.load(file)

    file.close()

    # {'age': 20, 'score': 90, 'name': 'Bob'}
    print(d)

2 JSON

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

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

  • 利用json.dumps()将python对象序列化成为一个符合json规范的python字符串,或者通过json.dump()先将python对象序列化成符合json规范的python字符串,然后再写到文件中。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import json

    d = dict(name='Bob', age=20, score=88)

    # '{"age": 20, "score": 88, "name": "Bob"}'
    json.dumps(d)

    # python对象序列化成符合json规范的python字符串,是str类型,因此以w打开,而非wb。
    file = open("dump.txt", "w")

    json.dump(d, file)

    file.close()

将 Python 对象序列化成符合 json 规范的 Python 字符串,实质上就是用一个 Python 字符串来表示这个 Python 对象(对于字符串来说,包括单引号或双引号,对于列表来说,包括 [],对于字典来说,包括 {})。 比如要表示 Python 字符串 '\n',则对应的符合 JSON 规范的 Python 字符串为 '"\\n"'。

  • 利用 json.loads() 将符合 JSON 规范的 Python 字符串反序列化成 Python 对象。或者利用 json.load() 先读取文件中的内容,然后再反序列化成一个 Python 对象。如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import json

    # 只能用r,不能用rb。
    file = open("dump.txt", "r")

    d = json.load(file)

    file.close()

    print(d)

3 自定义的Python对象序列化成符合JSON规范的Python字符串

上面是将python的内置类型对象序列化成符合json规范的Python字符串,但是很多情况下会碰到将自定义的类型的python对象序列化成json字符串。可以自定义一个函数,这个函数用于把各个属性及其值构造成一个内置的dict类对象,然后将这个函数传递给json.dumps()方法中的default参数即可。在调用json.dump()方法时,会将这个python对象传递给定义的这个函数。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import json

class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score

def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}

s = Student('Bob', 20, 88)
# {"age": 20, "name": "Bob", "score": 88}
# 会将s传递给student2dict这个函数。
print(json.dumps(s, default = student2dict))

不过,下次如果遇到一个Teacher类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意class的实例变为dict。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json

class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score


s = Student('Bob', 20, 88)

# obj.__dict__返回的是obj这个实例的所有属性及其值构成的dict。
# 会将s传递给定义的匿名函数
print(json.dumps(s, default = lambda obj: obj.__dict__))


Reference