CodeGym /Java 课程 /Python SELF ZH /管理序列化

管理序列化

Python SELF ZH
第 22 级 , 课程 2
可用

10.1 一切都按我的方式来!

有时候,你的对象里头会有很多指向各种服务对象的引用,这些引用你可能不想通过网络传输,或者根本无法通过网络传输:比如文件,数据库等的引用。

为了让序列化在这种情况下也能正常工作,设计者让类可以自己管理序列化。为此,使用了一些特殊的方法:__reduce__()__getstate__()__setstate__()。这些方法允许你指定对象如何被序列化和恢复。

管理序列化的主要方法有:

  • __reduce__():指定对象如何被序列化。
  • __getstate__():返回用于序列化的对象状态。
  • __setstate__(self, state):从状态恢复对象。

下面我会详细讲讲它们,以及如何一起使用。

10.2 方法 __reduce__()

方法 __reduce__() 返回一个元组,指定对象如何被序列化和反序列化。元组通常包含:

  • 用于恢复对象的函数或类的引用。
  • 该函数或类的参数元组。
  • 对象的额外状态(如果需要的话)。

例子:


import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
            
    def __reduce__(self):
        return (self.__class__, (self.value,))
            
    def __repr__(self):
        return f"CustomClass(value={self.value})"
            
# 创建对象
obj = CustomClass(42)
            
# 对象序列化
serialized_obj = pickle.dumps(obj)
print("序列化对象:", serialized_obj)
            
# 对象反序列化
deserialized_obj = pickle.loads(serialized_obj)
print("反序列化对象:", deserialized_obj)

默认情况下函数 __reduce__() 有如下行为:


class CustomClass:
    def __init__(self, value):
        self.value = value
        
    def __reduce__(self):
        # 类的定义
        cls = self.__class__
        # 构造函数的参数
        args = (self.value,)
        # 对象的状态
        state = self.__dict__
        return (cls, args, state)

它返回一个由三个对象组成的元组:

  • 当前类的引用
  • 构造函数的参数(元组)
  • 当前对象状态的引用

如果你满意这种默认行为,那就不需要重写 __reduce__()

10.3 读取和写入状态

方法 __getstate__()__setstate__()

这些方法用于在序列化和反序列化期间管理对象的状态。

  • __getstate__():返回应该被序列化的对象状态。
  • __setstate__(self, state):从状态恢复对象。

例子:

假如我们想保存对象的某些字段而排除其他字段。在 __getstate__() 方法中,我们需要:

  1. 复制当前对象状态(由服务字段 __dict__ 指定)到一个单独的变量——字典 state
  2. 删除其中不需要序列化的字段。
  3. 返回得到的对象作为 __getstate__() 函数的结果。

import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
        self.internal_state = "internal"
            
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['internal_state']  # 排除内部状态
        return state
            
    def __setstate__(self, state):
        self.__dict__.update(state)
        self.internal_state = "restored internal"  # 恢复内部状态
            
    def __repr__(self):
        return f"CustomClass(value={self.value}, internal_state={self.internal_state})"
            
# 创建对象
obj = CustomClass(42)
print("原始对象:", obj)
            
# 对象序列化
serialized_obj = pickle.dumps(obj)
print("序列化对象:", serialized_obj)
            
# 对象反序列化
deserialized_obj = pickle.loads(serialized_obj)
print("反序列化对象:", deserialized_obj)

在反序列化时,在 __setstate__() 函数中,我们做两件事情:

  1. 使用 update() 方法更新对象的当前状态。
  2. 字段 internal_state(以及其他不可序列化字段)获得新值。
1
Опрос
操作目录,  22 уровень,  2 лекция
недоступен
操作目录
操作目录
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION