我有一个defaultdict,看起来像这样:
dict1 = defaultdict(lambda: defaultdict(int))
问题是,使用cPickle的我不能咸菜了。 一,我发现这里的解决方案是使用模块级的函数,而不是一个拉姆达。 我的问题是,什么是模块级的功能? 如何使用与cPickle的字典?
我有一个defaultdict,看起来像这样:
dict1 = defaultdict(lambda: defaultdict(int))
问题是,使用cPickle的我不能咸菜了。 一,我发现这里的解决方案是使用模块级的函数,而不是一个拉姆达。 我的问题是,什么是模块级的功能? 如何使用与cPickle的字典?
除了马亭的解释 :
模块级的功能是其在模块级上定义的函数,这意味着它不是一个类的实例的方法,它不嵌套在另一功能中,并且它是一个名称,而不是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)
泡椒想要存储的所有实例属性,并defaultdict
实例存储到一个参考default
调用。 泡椒递归在每个实例属性。
味酸无法处理的lambda表达式; 咸菜永远只能处理数据,而不是代码,lambda表达式包含代码。 函数可以腌制,但就像类定义只有当功能可以导入 。 在模块级定义的函数可以导入。 泡椒只是存储在这种情况下,一个字符串,函数的完整“路径”需要进口,再取储存时参考。
但是,您可以使用partial
来实现:
>>> from collections import defaultdict
>>> from functools import partial
>>> pickle.loads(pickle.dumps(defaultdict(partial(defaultdict, int))))
defaultdict(<functools.partial object at 0x94dd16c>, {})
要做到这一点,只写你想写的代码。 我会用莳萝 ,可序列化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>, {})
如果你不关心保留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)
目前,我正在做类似的问题拗造型的东西,不过,我使用defaultdict的子类,有作为default_factory一个成员函数。 为了让我的代码工作正常(我需要在运行时定义的函数),我只是简单地添加一些代码编写的对象进行酸洗。
代替:
...
pickle.dump(dict, file)
...
我用这个:
....
factory = dict.default_factory
dict.default_factory = None
pickle.dump(dict, file)
dict.default_factory = factory
...
这不是我作为我的树确切的代码作为请求索引(所以我用一个递归成员函数做前/后咸菜操作),这创造了同树的类型的实例对象,但这种模式也回答了这个问题。
dict1 = defaultdict(lambda: defaultdict(int))
cPickle.dump(dict(dict1), file_handle)
工作对我来说