不能咸菜defaultdict(Can't pickle defaultdict)

2019-09-02 06:09发布

我有一个defaultdict,看起来像这样:

dict1 = defaultdict(lambda: defaultdict(int))

问题是,使用cPickle的我不能咸菜了。 一,我发现这里的解决方案是使用模块级的函数,而不是一个拉姆达。 我的问题是,什么是模块级的功能? 如何使用与cPickle的字典?

Answer 1:

除了马亭的解释 :

模块级的功能是其在模块级上定义的函数,这意味着它不是一个类的实例的方法,它不嵌套在另一功能中,并且它是一个名称,而不是lambda函数“真正的”功能。

所以,咸菜你defaultdict ,与模块级的功能,而不是lambda函数创建它:

def dd():
    return defaultdict(int)

dict1 = defaultdict(dd) # dd is a module-level function

比你可以泡制它

tmp = pickle.dumps(dict1) # no exception
new = pickle.loads(tmp)


Answer 2:

泡椒想要存储的所有实例属性,并defaultdict实例存储到一个参考default调用。 泡椒递归在每个实例属性。

味酸无法处理的lambda表达式; 咸菜永远只能处理数据,而不是代码,lambda表达式包含代码。 函数可以腌制,但就像类定义只有当功能可以导入 。 在模块级定义的函数可以导入。 泡椒只是存储在这种情况下,一个字符串,函数的完整“路径”需要进口,再取储存时参考。



Answer 3:

但是,您可以使用partial来实现:

>>> from collections import defaultdict
>>> from functools import partial
>>> pickle.loads(pickle.dumps(defaultdict(partial(defaultdict, int))))
defaultdict(<functools.partial object at 0x94dd16c>, {})


Answer 4:

要做到这一点,只写你想写的代码。 我会用莳萝 ,可序列化lambda表达式和defaultdicts。 莳萝可序列化的Python几乎所有的东西。

>>> import dill
>>> from collections import defaultdict
>>>
>>> dict1 = defaultdict(lambda: defaultdict(int))
>>> pdict1 = dill.dumps(dict1)
>>> _dict1 = dill.loads(pdict1)
>>> _dict1
defaultdict(<function <lambda> at 0x10b31b398>, {})


Answer 5:

如果你不关心保留defaultdict类型,将其转换:

fname = "file.pkl"

for value in nested_default_dict:
    nested_default_dict[value] = dict(nested_default_dict[value])
my_dict = dict(nested_default_dict)

with open(fname, "wb") as f:
    pickle.dump(my_dict, f)  # Now this will work

我认为这是当你是酸洗,因为一个伟大的选择,对象很可能是在它的最终形态......,如果真的再需要defaultdict类型,你可以简单地转换为你unpickle回来后:

for value in my_dict:
    my_dict[value] = defaultdict(type, my_dict[value])
nested_default_dict = defaultdict(type, my_dict)


Answer 6:

目前,我正在做类似的问题拗造型的东西,不过,我使用defaultdict的子类,有作为default_factory一个成员函数。 为了让我的代码工作正常(我需要在运行时定义的函数),我只是简单地添加一些代码编写的对象进行酸洗。

代替:

...
pickle.dump(dict, file)
...

我用这个:

....
factory = dict.default_factory
dict.default_factory = None
pickle.dump(dict, file)
dict.default_factory = factory
...

这不是我作为我的树确切的代码作为请求索引(所以我用一个递归成员函数做前/后咸菜操作),这创造了同树的类型的实例对象,但这种模式也回答了这个问题。



Answer 7:

dict1 = defaultdict(lambda: defaultdict(int))
cPickle.dump(dict(dict1), file_handle)

工作对我来说



文章来源: Can't pickle defaultdict