如何同时序列化类变量和实例变量?

7 投票
3 回答
2566 浏览
提问于 2025-04-27 23:50

pickle的文档中提到,“当我们把一个类的实例进行序列化时,它所属类的数据不会被一起序列化,只有实例的数据会被序列化。”有没有人能分享一下如何在序列化和反序列化时,把类变量和实例变量都包含进去的方法呢?

暂无标签

3 个回答

0

这里有一个只使用标准库模块的解决方案。只需执行下面的代码块,从那时起,pickle就会按照你想要的方式工作。正如Mike McKerns所说,dill在背后做了类似的事情。

相关讨论可以在这里找到。

import copy_reg


def _pickle_method(method):
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    return _unpickle_method, (func_name, obj, cls)


def _unpickle_method(func_name, obj, cls):
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)


copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
2

你可以通过使用标准库中的函数,轻松实现这个功能,具体方法是使用 __getstate____setstate__

class A(object):
  y = 1
  x = 0

  def __getstate__(self):
    ret = self.__dict__.copy()
    ret['cls_x'] = A.x
    ret['cls_y'] = A.y
    return ret

  def __setstate__(self, state):
    A.x = state.pop('cls_x')
    A.y = state.pop('cls_y')
    self.__dict__.update(state)
8

dill 替代 pickle,然后按照你之前的方式编写代码就可以了。

>>> class A(object):
...   y = 1
...   x = 0
...   def __call__(self, x):
...     self.x = x
...     return self.x + self.y
... 
>>> b = A()
>>> b.y = 4
>>> b(2)
6
>>> b.z = 5
>>> import dill
>>> _b = dill.dumps(b)
>>> b_ = dill.loads(_b)
>>> 
>>> b_.z
5
>>> b_.x
2
>>> b_.y
4
>>>
>>> A.y = 100
>>> c = A()
>>> _c = dill.dumps(c)
>>> c_ = dill.loads(_c)
>>> c_.y
100

撰写回答