Python 3如何知道如何pickle扩展类型,特别是Numpy数组?
numpy的阵列,作为扩展类型(使用在扩展的C API又名定义),声明Python解释的范围(外附加字段例如data
属性,它是一个Buffer Structure
,如在numpy的的array interface记载。
要能够将其序列化,Python 2的用惯了__reduce__
函数作为pickle协议的一部分,如在doc说明,并解释here。Python 3如何知道如何pickle扩展类型,特别是Numpy数组?
但是,即使__reduce__
仍然存在在Python 3,Pickle protocol
部(和Pickling and unpickling extension types
更多)被从文档中删除,所以目前还不清楚什么是。
此外,有涉及酸洗扩展类型的附加输入:
-
copyreg,描述为
Pickle interface constructor registration for extension types
,但有该copyreg模块本身中没有扩展类型的提。 - PEP 3118 -- Revising the buffer protocol它为Python 3发布了一个新的缓冲区协议。(也许自动对这个缓冲区协议进行酸洗)。
- 新式课堂:可以假设新式课堂对酸洗过程有影响。
那么,如何将所有这些涉及到numpy的数组:
- 不numpy的阵列实现特殊的方法,如
__reduce__
通知的Python如何腌制他们(或copyreg
)? Numpy对象仍然公开__reduce__
方法,但可能出于兼容性原因。 - Numpy是否使用Pickle开箱即用的Python C-API结构(如新的
buffer protocol
),所以为了泡制numpy数组,不需要补充任何东西?
Python 3 pickle
仍supports __reduce__
,它涵盖在Pickling Class Instances section下。
numpy的支持在这方面没有改变;它在阵列上实现__reduce__
支持酸洗中任一的Python 2或3:
>>> import numpy
>>> numpy.array(0).__reduce__()
(<built-in function _reconstruct>, (<class 'numpy.ndarray'>, (0,), b'b'), (1,(), dtype('int64'), False, b'\x00\x00\x00\x00\x00\x00\x00\x00'))
返回一个三元素的元组,由一个功能对象的重新创建的值,的参数为函数的元组,和一个状态元组通过否newinstance.__setstate__()
。
那么在[Pickling和Unpickling扩展类型](https://docs.python.org/2.7/library/pickle.html#pickling-and-unpickling-extension-types)中说什么仍然是正确的?为什么他们将'__reduce__'文件从'扩展类型'移动到更一般的'类实例'部分? – Phylliade
@Phylliade:是的,一切都是真的。该方法并不是专用于扩展类型的(并且自定义Python类和扩展类型之间的界线在很大程度上已被模糊)。 –
@Phylliade:'__reduce__'是较低级的复制协议实现;如果可能的话,自定义Python类应该实现更高级别的('__getnewargs_ex__'/'__getstate__' /'__setstate__')方法),然后使用默认的__reduce__实现。 –
'__reduce__'仍然存在于Python 3中。 –
.. [这里是'__reduce__'在Python 3中提到的文档](https://docs.python.org/3/library/pickle。 HTML?亮点=泡菜#对象.__ reduce__)。 – Phillip
关键是,即使'reduce'仍然存在,删除'reduce'文档中的扩展类型也被删除。但是,据说接受的答案(以及以下评论)指出,这仍然是正确的。 – Phylliade