在程序运行的过程中,所有的变量都是在内存中。
pickle模块
(1)把变量从内存中变成可存储或传输的过程,称之为序列化。Python中叫pickling,其他语言中也被称为serialization,marshalling,flattening等,都是相同的意思。
(2)序列化之后,就可以把序列化后的内容(序列化后的内容是一个Bytes)写入磁盘,或者通过网络传输到别的机器上。
(3)把变量内容从序列化的对象重新读到内存里,称之为反序列化,即unpickling。
(4)Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用pickle保存那些不重要的数据,不能成功地反序列化也没关系。
……………………………………………………………………………………
把一个对象序列化并写入文件,有两种方法:
(1)pickle.dumps( )方法
step1:先把任意对象序列化成一个bytes;step2:把这个序列化后的内容bytes写入文件。
(2)pickle.dump( )方法
直接把对象序列化后写入一个file-like Object。
………………………………………………………………………………………………
同序列化一样,当要把对象从磁盘读到内存时,有两种方法:
(1)pickle.loads( ):可以先把内容读到一个bytes,然后用pickle.loads( )方法反序列化出对象。
(2)pickle.load( ):直接用pickle.load( )方法从一个file-like Object中直接反序列化出对象。
注意:反序列化后的变量对象和原来的变量是完全不相干的,它们只是内容相同而已。
JSON
Python内置的json模块可以实现从Python对象到JSON格式的转换。
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,原因如下:
(1)JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。
(2)JSON是标准格式,比XML更快,而且可以直接在Web页面中读取。
(3)JSON表示的对象就是标准的JavaScript语言的对象。
JSON和Python内置的数据类型对应如下:
JSON类型 | Python类型 |
{ } | dict |
[ ] | list |
"string" | str |
1234.56 | int或float |
true/false | True/False |
null | None |
注: 把Python对象转换成JSON格式时,只要是上面表格中列举的Python类型即可,其他类型,例如变量,就会报错。
把Python对象转换成JSON格式:
(1)json.dumps( )方法:返回一个str,内容就是标准的JSON
(2)json.dump( )方法:序列化为json后可以直接写入一个file-like Object。
……………………………………………………………………………………………………
要把JSON反序列化为Python对象
json.loads( )方法:把json的字符串反序列化。
json.load( )方法 :从file-like Object 中读取字符串并反序列化。
注:由于JSON标准规定JSON编码是UTF-8,所以我们总是能正确地在Python的str与JSON的字符串之间转换。
JSON进阶
通常类class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量也有少数例外,比如定义了__slots__.
import json class Student(object): def __init__(self,name,age): self.name=name self.age=age jack=Student("jack",23) #创建一个实例 # mask1=json.dumps(jack) #这种会报错,因为不是字典格式dict mask2=json.dumps(jack,default=lambda x:x.__dict__) #转换为字典格式,使用default参数 def dic2str(d): return Student(d["name"],d["age"]) mask3=json.loads(mask2,object_hook=dic2str) #先转换为字典格式,再实用函数转换为实例对象 print(mask2) print(mask3)
小结
Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。
json模块的dumps( )和loads( )函数是定义得非常好的接口的典范。使用时只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。
序列化是将对象的状态信息转换为可以存储或传输的窗体的过程
在序列化期间,对象将其当前状态写入到临时或持久性存储区