How can I use pickle to save a dict?

前端 未结 9 2203
说谎
说谎 2020-11-22 06:45

I have looked through the information that the Python docs give, but I\'m still a little confused. Could somebody post sample code that would write a new file then use pickl

9条回答
  •  有刺的猬
    2020-11-22 07:38

    In general, pickling a dict will fail unless you have only simple objects in it, like strings and integers.

    Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
    [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from numpy import *
    >>> type(globals())     
    
    >>> import pickle
    >>> pik = pickle.dumps(globals())
    Traceback (most recent call last):
      File "", line 1, in 
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
        Pickler(file, protocol).dump(obj)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
        self.save(obj)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
        f(self, obj) # Call unbound method with explicit self
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
        self._batch_setitems(obj.iteritems())
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
        save(v)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
        rv = reduce(self.proto)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
        raise TypeError, "can't pickle %s objects" % base.__name__
    TypeError: can't pickle module objects
    >>> 
    

    Even a really simple dict will often fail. It just depends on the contents.

    >>> d = {'x': lambda x:x}
    >>> pik = pickle.dumps(d)
    Traceback (most recent call last):
      File "", line 1, in 
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
        Pickler(file, protocol).dump(obj)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
        self.save(obj)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
        f(self, obj) # Call unbound method with explicit self
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
        self._batch_setitems(obj.iteritems())
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
        save(v)
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
        f(self, obj) # Call unbound method with explicit self
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
        (obj, module, name))
    pickle.PicklingError: Can't pickle  at 0x102178668>: it's not found as __main__.
    

    However, if you use a better serializer like dill or cloudpickle, then most dictionaries can be pickled:

    >>> import dill
    >>> pik = dill.dumps(d)
    

    Or if you want to save your dict to a file...

    >>> with open('save.pik', 'w') as f:
    ...   dill.dump(globals(), f)
    ... 
    

    The latter example is identical to any of the other good answers posted here (which aside from neglecting the picklability of the contents of the dict are good).

提交回复
热议问题