在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88)
可以随时修改变量,比如把 我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
Python提供两个模块来实现序列化:
首先,我们尝试把一个对象序列化并写入文件: >>> d = dict(name='Bob', age=20, score=88) >>> pickle.dumps(d) "(dp0\nS'age'\np1\nI20\nsS'score'\np2\nI88\nsS'name'\np3\nS'Bob'\np4\ns."
>>> f = open('dump.txt', 'wb') >>> pickle.dump(d, f) >>> f.close()
看看写入的
当我们要把对象从磁盘读到内存时,可以先把内容读到一个 >>> f = open('dump.txt', 'rb') >>> d = pickle.load(f) >>> f.close() >>> d {'age': 20, 'score': 88, 'name': 'Bob'} 变量的内容又回来了! 当然,这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。 JSON如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是 一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读 取,非常方便。 JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
Python内置的 >>> import json >>> d = dict(name='Bob', age=20, score=88) >>> json.dumps(d) '{"age": 20, "score": 88, "name": "Bob"}'
要把JSON反序列化为Python对象,用 >>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' >>> json.loads(json_str) {u'age': 20, u'score': 88, u'name': u'Bob'}
有一点需要注意,就是反序列化得到的所有字符串对象默认都是 JSON进阶
Python的 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) print(json.dumps(s))
运行代码,毫不留情地得到一个 Traceback (most recent call last): ... TypeError: <__main__.Student object at 0x10aabef50> is not JSON serializable
错误的原因是
如果连
别急,我们仔细看看 https://docs.python.org/2/library/json.html#json.dumps
这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把
可选参数 def student2dict(std): return { 'name': std.name, 'age': std.age, 'score': std.score } print(json.dumps(s, default=student2dict))
这样,
不过,下次如果遇到一个 print(json.dumps(s, default=lambda obj: obj.__dict__))
因为通常
同样的道理,如果我们要把JSON反序列化为一个 def dict2student(d): return Student(d['name'], d['age'], d['score']) json_str = '{"age": 20, "score": 88, "name": "Bob"}' print(json.loads(json_str, object_hook=dict2student)) 运行结果如下: <__main__.Student object at 0x10cd3c190>
打印出的是反序列化的 小结
Python语言特定的序列化模块是
转载请保留固定链接: https://linuxeye.com/program/2428.html |