How to check if an object is pickleable

后端 未结 3 1890
忘掉有多难
忘掉有多难 2020-12-18 19:47

I have a list of objects of various types that I want to pickle. I would like to pickle only those which are pickleable. Is there a standard way to check if an object is of

3条回答
  •  情书的邮戳
    2020-12-18 20:03

    There's the dill.pickles method in dill package that does just that.

    >>> class Foo(object):
    ...   x = iter([1,2,3])
    ... 
    >>> f = Foo()     
    >>> 
    >>> dill.pickles(f)
    False
    

    We can use methods in dill to look for what causes the failure.

    >>> dill.detect.badtypes(f)
    
    >>> dill.detect.badtypes(f, depth=1)
    {'__setattr__': , '__reduce_ex__': , '__reduce__': , '__str__': , '__format__': , '__getattribute__': , '__class__': , '__delattr__': , '__subclasshook__': , '__repr__': , '__hash__': , 'x': , '__sizeof__': , '__init__': }
    >>> dill.detect.badtypes(f, depth=1).keys()
    ['__setattr__', '__reduce_ex__', '__reduce__', '__str__', '__format__', '__getattribute__', '__class__', '__delattr__', '__subclasshook__', '__repr__', '__hash__', 'x', '__sizeof__', '__init__']
    

    So, the only thing that's failing that's not a "built-in" method of the class is x… so that's a good place to start. Let's check 'x', then replace it with something else if it's the problem.

    >>> dill.pickles(Foo.x)
    False
    >>> Foo.x = xrange(1,4)
    >>> dill.pickles(Foo.x)
    True
    

    Yep, x was causing a failure, and replacing it with an xrange works because dill can pickle an xrange. What's left to do?

    >>> dill.detect.badtypes(f, depth=1).keys()
    []
    >>> dill.detect.badtypes(f, depth=1)       
    {}
    >>> dill.pickles(f)                 
    True
    >>> 
    

    Apparently (likely because references to x in the class __dict__ now pickle), f now pickles… so we are done.

    dill also provides trace to show the exact path in pickling the object.

    >>> dill.detect.trace(True)
    >>> dill.pickles(f)
    T2: 
    F2: 
    T1: 
    F2: 
    T1: 
    D2: 
    Si: xrange(1, 4)
    F2: 
    D2: 
    True
    

提交回复
热议问题