如何检查对象是否为pickleab

2024-04-24 03:24:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个列表,列出了各种类型的对象。我只想腌制那些可以腌制的。除了尝试pickle之外,是否有标准方法检查对象是否属于pickle类型?

文档中说,如果发生pickle异常,可能是在将某些字节写入文件之后,因此尝试pickle对象作为测试似乎不是一个好的解决方案。

我看到了this post但它没有回答我的问题。


Tags: 文件对象方法文档类型列表标准字节
3条回答

在这种情况下,我建议进行duck测试。尝试pickle到一个临时文件或内存文件中(如果您认为合适),然后如果失败,则丢弃结果,如果重命名成功。

为什么?

在python中,可以通过两种方式检查对象是否具有某些属性。

检查对象是否是某个Abstract Base Class的实例。E、 g.^{}“数字层次结构的根。如果只想检查参数x是否为数字,而不考虑是哪种类型,请使用isinstance(x,number)。”

或者尝试一下,然后处理异常。这在很多情况下都会发生。Python哲学是以鸭为基础的。Duck typingduck testEAFP是关键字。

我甚至相信,在来自社区的压力下,python3已经正确地引入了第一个python3,而许多人仍然坚信使用python的方法是使用duck。

AFAIK没有可以检查的特殊先决条件,也没有在pickling的情况下可以检查对象的任何^{}。剩下的就是鸭子了。

也许可以尝试其他的东西,但可能不值得。人工反省,很难初步查明是否适合腌制。

^{} package中有一个dill.pickles方法可以做到这一点。

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

我们可以使用dill中的方法来查找导致失败的原因。

>>> dill.detect.badtypes(f)
<class '__main__.Foo'>
>>> dill.detect.badtypes(f, depth=1)
{'__setattr__': <type 'method-wrapper'>, '__reduce_ex__': <type 'builtin_function_or_method'>, '__reduce__': <type 'builtin_function_or_method'>, '__str__': <type 'method-wrapper'>, '__format__': <type 'builtin_function_or_method'>, '__getattribute__': <type 'method-wrapper'>, '__class__': <type 'type'>, '__delattr__': <type 'method-wrapper'>, '__subclasshook__': <type 'builtin_function_or_method'>, '__repr__': <type 'method-wrapper'>, '__hash__': <type 'method-wrapper'>, 'x': <type 'listiterator'>, '__sizeof__': <type 'builtin_function_or_method'>, '__init__': <type 'method-wrapper'>}
>>> dill.detect.badtypes(f, depth=1).keys()
['__setattr__', '__reduce_ex__', '__reduce__', '__str__', '__format__', '__getattribute__', '__class__', '__delattr__', '__subclasshook__', '__repr__', '__hash__', 'x', '__sizeof__', '__init__']

所以,唯一失败的不是类的“内置”方法是x……所以这是一个很好的开始。让我们检查一下“x”,如果是问题的话,用别的东西代替它。

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

是的,x导致了一个失败,而用xrange替换它是可行的,因为dill可以腐蚀一个xrange。还有什么事要做?

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

显然(很可能是因为类中对x的引用现在pickle),f现在pickle…所以我们完成了。

dill还提供trace来显示pickling对象的确切路径。

>>> dill.detect.trace(True)
>>> dill.pickles(f)
T2: <class '__main__.Foo'>
F2: <function _create_type at 0x10e79b668>
T1: <type 'type'>
F2: <function _load_type at 0x10e79b5f0>
T1: <type 'object'>
D2: <dict object at 0x10e7c6168>
Si: xrange(1, 4)
F2: <function _eval_repr at 0x10e79bcf8>
D2: <dict object at 0x10e7c6280>
True

dill允许对内置的更多内容进行酸洗。

我想,这应该能让你做什么:

def is_picklable(obj):
  try:
    pickle.dumps(obj)

  except pickle.PicklingError:
    return False
  return True

相关问题 更多 >