0

How do I create pickle file of function (defaultDict)? The error I get is can't 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()

StackTrace:

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
Merlin
  • 19,645
  • 34
  • 108
  • 190

2 Answers2

5

The cPickle error message is a bit misleading; the pickle version is better. It's not that you can't pickle functions; it's that they need to be available by their __name__. A lambda has __name__ set to '<lambda>', so it's not picklable. Define it with def:

def tree():
    return defaultdict(tree)

and it will be picklable. (You'll still need a matching definition of tree available when you unpickle it.)

user2357112 supports Monica
  • 215,440
  • 22
  • 321
  • 400
1

A simple workaround would be to implement your tree data-structure differently, without 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
f = open("hapP.pkl", "wb")
pickle.dump(hapPkl, f)
f.close()
martineau
  • 99,260
  • 22
  • 139
  • 249
  • what would be the benefits of this? – Merlin Jun 20 '16 at 19:15
  • It's arguably a better way to do it. An important one is that it prints and pretty-prints (`pprint()`) like a normal dictionary. See [_What is the best way to implement nested dictionaries in Python?_](http://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries-in-python/19829714#19829714) – martineau Jun 20 '16 at 23:08