Python 如何pickle和unpickle从defaultdict继承的类的实例?

Python 如何pickle和unpickle从defaultdict继承的类的实例?,python,pickle,Python,Pickle,我有一个类继承自defaultdict,如下所示: class listdict(defaultdict): def __init__(self): defaultdict.__init__(self, list) 我可以腌制它,但当我解开它时,会发生这种情况: ('__init__() takes exactly 1 argument (2 given)', <class 'listdict'>, (<type 'list'>,)) ('\u

我有一个类继承自
defaultdict
,如下所示:

class listdict(defaultdict):
    def __init__(self):
        defaultdict.__init__(self, list)
我可以腌制它,但当我解开它时,会发生这种情况:

('__init__() takes exactly 1 argument (2 given)', <class 'listdict'>, (<type 'list'>,))
('\uuuu init\uuuuuuuu()正好接受1个参数(给定2个),(,)

该类没有定义pickle协议的任何特殊方法。正常
defaultdict(列表)
的酸洗和解酸洗工作正常。有人能告诉我吗?

该错误表明您的“listdict”类应该接受一个参数(隐式自我),但得到两个参数

您的类继承自defaultdict,并定义了一个初始值设定项。此初始值设定项调用defaultdict的初始值设定项并将“list”传递给它,在本例中,它可能是函数或类。(我懒得检查一下)

您可能的意思是这样做:

class listdict(defaultdict):
    def __init__(self, list):
        defaultdict.__init__(self, list)
现在,当listdict使用给定列表初始化时,它将该列表传递给defaultdict的构造函数,而不是传递对全局列表的引用


(也就是说,使用与通用全局方法和类(如“str”、“list”等)相同的名称被认为是不好的风格,原因与您混淆的原因相同)。

类型通过定义一个或多个(相当大的)方法集来定义它的实例是如何被pickle的。每个人都有自己微妙的行为。看见在
collections.defaultdict
的情况下,它使用
\uuuuuuuuuuuuuuuuuu
方法:

>>> l = collections.defaultdict(list)
>>> l.__reduce__()
(<type 'collections.defaultdict'>, (<type 'list'>,), None, None, <dictionary-itemiterator object at 0x7f031fb3c470>)
这只是一个粗略的例子,因为酸洗还有很多(比如
\uuuu reduce\uu ex\uuuu
),而且都相当复杂。在这种情况下,使用
\uu getinitargs\uu
可能更方便

或者,您可以使类的
\uuuu init\uuu
方法采用可选的可调用、默认为
列表
,或者您可以只使用函数而不是类:

def listdict():
    return collections.defaultdict(list)

list
是一个类。OP传递的不是一个特定的列表,而是一个类,作为一个可调用的类,它本身充当工厂函数,
defaultdict
的构造函数将其作为一个参数。使用
listdict
list
作为一个参数,违背了对
defaultdict
进行子类化的目的。但是,这个问题肯定会时不时地发生,“这是故意的吗?”他可能正在测试它,并计划稍后向类中添加更多功能。您使用的是
pickle
还是
cpickle
?谢谢!我决定选择默认参数,因为这似乎是最简单、最稳定的选项。真的吗?功能更简单:)谢谢。这帮助我解决了使用
[0]*self.\u size
作为默认值,并在酸洗过程中获得
\u size
参数的问题。
def listdict():
    return collections.defaultdict(list)