Python 使用 __getstate__ 和 __setstate__ 魔法方法
2021-03-21 更新__getstate__ 与 __setstate__ 两个魔法方法分别用于Python 对象的序列化与反序列化在序列化时, _getstate__ 可以指定将那些信息记录下来, 而 __setstate__指明如何利用已记录的信息
·
__getstate__ 与 __setstate__ 两个魔法方法分别用于Python 对象的序列化与反序列化
在序列化时, _getstate__ 可以指定将那些信息记录下来, 而 __setstate__ 指明如何利用已记录的信息
先创建一个基类
class Demo:
def __init__(self, name, age=0):
self.name = name
self.age = age
def __str__(self):
return f"name: {self.name}\nage: {self.age}"
继承Demo
, 并实现 __getstate__ 与 __setstate__ 方法
class DemoState1(Demo):
# 反序列化时调用, state 是 __getstate__ 的返回对象
def __setstate__(self, state):
print("invoke __setstate__")
# 将记录的信息("Python3") 赋给 name
self.name = state
self.age = 31
# 序列化时调用
def __getstate__(self):
print("invoke __getstate__")
# 记录信息 “Python3”
return "Python3"
测试调用流程
In [3]: import pickle
In [4]: demo_1 = DemoState1("None") # "None" 0
In [5]: print(demo_1)
name: None
age: 0
In [6]: demo_bytes_1 = pickle.dumps(demo_1) # 序列化为字节串
invoke __getstate__
In [7]: print(demo_bytes_1) # 仅对象中的字符串信息是可读的
b'\x80\x03c__main__\nDemoState1\nq\x00)\x81q\x01X\x07\x00\x00\x00Python3q\x02b.'
In [8]: demo_object_1 = pickle.loads(demo_bytes_1)
invoke __setstate__
In [9]: print(demo_object_1)
name: Python3
age: 31
可以省略 __setstate__, 但 __getstate__ 必须返回一个字典, 字典的内容被加载到当前的对象
class DemoState2(Demo):
# 省略 __setstate__
# 自动将 __getstate__ 的返回对象添加到当前对象的属性
# 序列化时调用
def __getstate__(self):
# 必须返回字典
state = {"name": "C", "age": 50, "address": "Bell Lab"}
return state
测试
In [11]: demo_2 = DemoState2("None")
In [12]: demo_bytes_2 = pickle.dumps(demo_2)
In [13]: print(pickle.loads(demo_bytes_2))
name: C
age: 50
对象本身没有 address 属性, 因此反序列化时被忽略了
如果 __getstate__ 与 __setstate__ 都省略, 那么就是默认情况, 自动保存和加载对象的属性字典 __dict__
In [14]: js = Demo("JavaScript", 26)
In [15]: js.__dict__ # 对象的属性字典
Out[16]: {'name': 'JavaScript', 'age': 26}
In [17]: js_bytes = pickle.dumps(js)
In [18]: print(pickle.loads(js_bytes))
name: JavaScript
age: 26
大多数时候保持默认情况即可, 但是遇到不可序列化的对象, 例如 self.file = open("filename")
, 就需要忽略掉该属性
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)