简体   繁体   English

Pickle两个类变量和实例变量?

[英]Pickle both class variables and instance variables?

The pickle documentation states that "when class instances are pickled, their class's data are not pickled along with them. Only the instance data are pickled." pickle文档指出“当类实例被腌制时,它们的类的数据不会随之被腌制。只有实例数据被腌制。” Can anyone provide a recipe for including class variables as well as instance variables when pickling and unpickling? 任何人都可以在酸洗和去除时提供包含类变量和实例变量的方法吗?

Use dill instead of pickle, and code exactly how you probably have done already. 使用dill代替泡菜,并准确编码您可能已经完成的工作。

>>> 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

You can do this easily using the standard library functions by using __getstate__ and __setstate__ : 您可以使用__getstate____setstate__使用标准库函数轻松完成此__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)

Here's a solution using only standard library modules. 这是一个仅使用标准库模块的解决方案。 Simply execute the following code block, and from then on pickle behaves in the desired way. 只需执行以下代码块,从那时起pickle就会以所需的方式运行。 As Mike McKerns was saying, dill does something similar under the hood. 正如Mike McKerns所说, dill做了类似的事情。

Based on relevant discussion found here . 根据此处的相关讨论。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM