知行编程网知行编程网  2022-12-03 08:00 知行编程网 隐藏边栏  15 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于python怎么序列化的相关知识,包括python django,以及python json这些编程知识,希望对大家有参考作用。


如何在python中序列化


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学习网,免费的在线学习
,欢迎关注!

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享