如何腌制使用 lambda 函数的 defaultdict?

How to pickle a defaultdict which uses a lambda function?

如何创建函数 (defaultDict) 的 pickle 文件?我得到的错误是 不能pickle function objects

from collections import defaultdict
dtree = lambda: defaultdict(tree)

try:    import cPickle as pickle
except: import pickle

#Create defaultdict  object:
hapPkl = dtree()

#Create Pickle file
f  = open("hapP.pkl","wb")
pickle.dump(hapPkl,f)
f.close()

堆栈跟踪:

TypeError                                 Traceback (most recent call last)
<ipython-input-287-376cac3b4f0d> in <module>()
      1 f  = open("hapP.pkl","wb")
----> 2 pickle.dump(hapPkl,f)
      3 f.close()

/usr/lib64/python2.7/copy_reg.pyc in _reduce_ex(self, proto)
     68     else:
     69         if base is self.__class__:
---> 70             raise TypeError, "can't pickle %s objects" % base.__name__
     71         state = base(self)
     72     args = (self.__class__, base, state)

TypeError: can't pickle function objects

cPickle 错误信息有点误导; pickle 版本更好。并不是说你不能 pickle 函数;而是他们需要 __name__ 可用。 lambda 将 __name__ 设置为 '<lambda>',因此它不可 picklable。定义为 def:

def tree():
    return defaultdict(tree)

而且它可以腌制。 (当你解开它时,你仍然需要 tree 的匹配定义。)

一个简单的解决方法是以不同的方式实现树数据结构,没有 defaultdict:

class DTree(dict):
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

try:    import cPickle as pickle
except: import pickle

#Create dtree object:
hapPkl = DTree()

#Create Pickle file
with open("hapP.pkl", "wb") as f:
    pickle.dump(hapPkl, f)