Pickle :同时使用 __getstate__ 和 __getnewargs__

Pickle : using both __getstate__ and __getnewargs__

我在 python 2.7 上使用 pickle。我正在尝试调用我覆盖的 __getstate____getnewargs__ 两种方法。我不能 pickle 属性 c 因为它是 classe D.

的一个实例
 nn = C(7, 2)
 nn.d = 1
 pickle.dump(nn, open('c_save.p', 'wb'))
 nn2 = pickle.load(open('c_save.p', 'rb'))
 print nn2.__dict__

Returns :

getstate was called
setstate was called
{'a': 7, 'b': 2, 'd': 1}

我没有看到应该创建属性 c__getnewargs__ 的调用。

我的代码:

import pickle

class D(object):
    def __init__(self, i, j):
        self.i = i
        self.j = j

class C(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.c = D(a, b)
        self.d = 0

    def __getstate__(self):
        print 'getstate was called'
        odict = self.__dict__.copy()
        del odict['c']
        return odict

    def __getnewargs__(self):
        print 'getnewargs was called'
        return (self.b,self.a)

    def __setstate__(self, dict):
        print 'setstate was called'
        self.__dict__.update(dict)

来自docs

New-style types can provide a getnewargs() method that is used for protocol 2.

对于pickle.dump

If the protocol parameter is omitted, protocol 0 is used.

因此,您必须将 pickle 协议显式设置为 2,如下所示:

pickle.dump(nn, open('c_save.p', 'wb'), protocol=2)