'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." Can anyone provide a recipe for including class variables as well as instance variables when pickling and unpickling?



Solution 1:[1]

You can do this easily using the standard library functions by using __getstate__ and __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)

Solution 2:[2]

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. As Mike McKerns was saying, dill does something similar under the hood.

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)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2