pickle模块,json模块
(1) 变量从内存到存储或传输的过程称为序列化。在Python中称为pickling,在其他语言中也称为serialization、marshalling、flattening等,都是一个意思。
(2) 序列化后,可以将序列化后的内容(序列化后的内容是一个Bytes)写入磁盘,或者通过网络传输给其他机器。
(3)从序列化后的对象中重新读取变量内容到内存中,称为反序列化,即unpickling。
(4) Pickle的问题和其他所有编程语言特有的序列化问题一样,就是只能在Python中使用,不同版本的Python之间可能不兼容。所以pickle只能用来保存那些不重要的数据,不能反序列化成功也没关系。
把一个对象序列化并写入文件,有两种方法:
(1)pickle.dumps()方法:将任意对象序列化为一个字节,然后将这个字节以一定的方式写入文件。
import pickle
d=dict(name='bob',age=23,score=98)
print(pickle.dumps(d))
(2)pickle.dump( )方法: 直接把对象序列化后写入一个file-like Object
import pickle
d=dict(name='shirley',age=23,score=98)
f=open('dump.txt','wb') #因为序列化之后是bytes,所以是wb
pickle.dump(d,f)
f.close()
#通过pickle.dump()将对象保存到文件中,通过下面语句可以查看写入的序列化内容
f=open("dump.txt",'rb')#rb
print(f.read())
pickle.dumps( ) 和pickle.dump( ) 的区别:在于中间过程是否需要多做一些操作。
对于前者,我们要多做一些操作;对于后者,我们不需要再做任何操作。
与序列化一样,有两种方法可以将对象从磁盘读取到内存:
(1)pickle.loads():可以先将内容读入一个字节,然后使用pickle.loads()方法反序列化对象
(2)pickle.load( ):直接用pickle.load( )方法从一个file-like Object中直接反序列化出对象
import pickle
f=open('dump.txt','rb')
s=pickle.load(f)
f.close()
print("反序列化后的对象s:",s)
运行结果: 反序列化后的对象s: {'score': 98, 'age': 23, 'name': 'shirley'}
注意:这个反序列化后的对象与原来的变量d完全无关,只是内容相同而已。
JSON
Python内置的json模块可以实现从Python对象到JSON格式的转换
(1) JSON表示为字符串,所有语言都可以读取,也可以方便地存储在磁盘上或通过网络传输。
(2) JSON是一种标准格式,速度比XML快,可以直接在网页中读取。
(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格式:json.dumps()方法、json.dump()方法(可以直接把JSON写成类文件的Object)
将JSON反序列化为Python对象:json.loads()方法、json.load()方法(前者反序列化JSON字符串,后者从类文件Object中读取字符串并反序列化)
实例:把Python对象变成一个JSON
import json
d=dict(name='shirley',age=23,score=98)
print(json.dumps(d))
print(isinstance(json.dumps(d),str)) #判断序列化后的内容类型
print(type(json.dumps(d)))#判断序列化后的内容类型
运行结果:
json.dumps(d): {"name": "shirley", "age": 23, "score": 98}
True
<class 'str'>
JSON字符串反序列化:
import json
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str))
print(type(json.loads(json_str)))
注意:由于JSON标准规定JSON编码为UTF-8,所以我们始终可以在Python字符串str和JSON字符串之间进行正确的转换。
JSON进阶
由于Python字典dict对象是上表所列的Python类型,所以字典dict可以直接序列化成JSON的{}。但是,很多情况下,更倾向于使用class来表示对象,比如定义Student类,然后进行序列化:
import json
class Student(object):
def __init__(self,name,age,score):
self.name=name
self.age=age
self.score=score
s=Student('Nancy',24,89)
print(json.dumps(s))
运行结果:
Traceback (most recent call last):
……………………………………
TypeError: <main.Student object at 0x0000000000844208> is not JSON serializable
错误的原因是:
Student 对象不是可序列化为 JSON 的对象。如果类的实例对象不能序列化成JSON,那肯定是不合理的。 (我的理解是class的实例对象s是一个变量,上面列出的Python类型中没有,所以报错)
前面的代码之所以无法将 Student 类实例序列化为 JSON,是因为默认情况下 dumps() 方法不知道如何将 Student 实例变成 JSON { } 对象。
解决办法是:定制JSON序列化
####对可选参数default进行设置,把任意class的实例变为dict
print(json.dumps(s, default=lambda obj: obj.__dict__))
通常,class类的实例都有一个dict属性,就是一个dict,用来存放实例变量(注意:是实例变量,即不同的实例,这个属性存放的变量是不同的,互不影响).也有一些例外,例如定义插槽
同理,要将JSON反序列化为Student对象实例,loads()方法首先转换一个dict对象,然后我们传入的object_hook函数负责将dict转换为Student实例
class Student(object):
def __init__(self,name,age,score):
self.name=name
self.age=age
self.score=score
import 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))
print(json.loads(json_str, object_hook=dict2student))
运行结果:
{'age': 20, 'score': 88, 'name': 'Bob'}
<main.Student object at 0x00000000007345C0>
打印出的是反序列化的实例对象。
小结
Python语言特有的序列化模块是pickle,但是如果你想让序列化更通用,更符合Web标准,可以使用json模块。
json 模块的 dumps() 和 loads() 函数是定义良好的接口的好例子。使用时只需传入一个必填参数即可。但是,当默认的序列化或反序列化机制不能满足我们的要求时,可以传入更多的参数来自定义序列化或反序列化规则,这样不仅界面简单易用,而且具有足够的可扩展性和灵活性。
python学习网,免费的在线学习
,欢迎关注!
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 如何在python中保留小数09/26
- ♥ python的枚举函数有什么用?09/03
- ♥ python中使用yield的注意事项10/17
- ♥ python没有数据类型吗?11/22
- ♥ python安装第三方函数库的方法12/03
- ♥ python字符串的常用方法有哪些09/12
内容反馈