Python Pickle失去了我的一个论点

Python Pickle失去了我的一个论点,python,multiple-inheritance,pickle,Python,Multiple Inheritance,Pickle,我在pickle上遇到了麻烦:我有一个棘手的用例,我没有得到我pickle对象的副本。如果我从 class OneArg(object): def __init__(self, somearg, *args, **kwargs): print "In OneArgs's init with args={} and kwargs={}".format(args, kwargs) self._somearg = somearg super(On

我在pickle上遇到了麻烦:我有一个棘手的用例,我没有得到我pickle对象的副本。如果我从

class OneArg(object):
    def __init__(self, somearg, *args, **kwargs):
        print "In OneArgs's init with args={} and kwargs={}".format(args, kwargs)
        self._somearg = somearg
        super(OneArg, self).__init__(*args, **kwargs)

class OneArgSubclass(OneArg, OrderedDict):
    def __init__(self, *args, **kwargs):
        print "In OneArgSubclass's init with args={} and kwargs={}".format(args, kwargs)
        super(OneArgSubclass, self).__init__(*args, **kwargs)


def verbose_pickle_dumps (obj):
    result = pickle.dumps(obj)
    print result
    return result


oas = OneArgSubclass("SOMEARG")
oas['spam'] = 'eggs'
oas_red = pickle.loads(verbose_pickle_dumps(oas))
print "oas_red.keys():", oas_red.keys()
以下是我得到的输出:

In OneArgSubclass's init with args=('SOMEARG',) and kwargs={}
In OneArgs's init with args=() and kwargs={}
oas.keys(): ['spam']

c__main__
OneArgSubclass
p0
((lp1
(lp2
S'spam'
p3
aS'eggs'
p4
aatp5
Rp6
(dp7
S'_somearg'
p8
S'SOMEARG'
p9
sb. 

In OneArgSubclass's init with args=([['spam', 'eggs']],) and kwargs={}
In OneArgs's init with args=() and kwargs={}
oas_red.keys(): []
我可以看到,当我对oas进行pickle时,'spam'/'eggs'键/值对就在那里,_somearg的值也在那里。但是请注意,字符串“OrderedDict”不会出现。当我尝试从pickle加载oas时,它不会拾取字符串'SOMEARG',因此字典的内容最终会变成_SOMEARG的值


我已经看过了,oas既没有uuu getinitargs uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果我使用常规dict而不是OrderedDict,那么代码就可以工作(pickle表示看起来非常不同,包括提到“copy_reg”),因此我认为问题可能在于pickle和OrderedDict之间的兼容性。但是,当我单独使用OrderedDict时,pickle可以正常工作。

当你pickle一些东西时,可以用来提取数据以在取消pickle时重新创建对象。您遇到的问题是,
OrderedDict
定义了其中一个(
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
),但它返回的内容与您的
\uuuuuuuuu init\uuuuuuuuuuuu
不兼容,因此您需要编写自己的:

def __reduce__(self):
    return (self.__class__, (self._somearg, tuple(self.items())))

当你pickle一些东西时,有一些可以用来提取数据以在取消pickle时重新创建对象。您遇到的问题是,
OrderedDict
定义了其中一个(
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
),但它返回的内容与您的
\uuuuuuuuu init\uuuuuuuuuuuu
不兼容,因此您需要编写自己的:

def __reduce__(self):
    return (self.__class__, (self._somearg, tuple(self.items())))

您可能希望为您的类实现一个
\uuuu repr\uuuu()
方法,如下所示:

在他们的示例中,他们从
orderedict
派生一个类,并以这种方式实现
\uuuu repr\uuu()
方法

def __repr__(self):
        return '{%s}' % ', '.join([': '.join([repr(k),str(v)]) \
                                   for k,v in zip(self.keys(), self.values())])
当类
\uuuu init()\uuuuu
运行时

class OrderedDict(dict):

    def __init__(self, d = None):
        self._keys = []
        if d == None: d = {}
        self.update(d)

您可能希望为您的类实现一个
\uuuu repr\uuuu()
方法,如下所示:

在他们的示例中,他们从
orderedict
派生一个类,并以这种方式实现
\uuuu repr\uuu()
方法

def __repr__(self):
        return '{%s}' % ', '.join([': '.join([repr(k),str(v)]) \
                                   for k,v in zip(self.keys(), self.values())])
当类
\uuuu init()\uuuuu
运行时

class OrderedDict(dict):

    def __init__(self, d = None):
        self._keys = []
        if d == None: d = {}
        self.update(d)