Python 3 如何知道如何 pickle 扩展类型,尤其是 Numpy 数组?

How does Python 3 know how to pickle extension types, especially Numpy arrays?

Numpy 数组,作为扩展类型(又名在扩展中使用 C API 定义),声明 Python 解释器范围之外的其他字段(例如 data 属性,这是一个 Buffer Structure,如 Numpy 的 array interface.
中所述 为了能够序列化它,Python 2 曾经使用 __reduce__ 函数作为 pickle 协议的一部分,如 doc, and explained here.

中所述

但是,即使 __reduce__ 仍然存在于 Python 3 中,Pickle protocol 部分(更不用说 Pickling and unpickling extension types 部分)已从文档中删除,因此它是不清楚什么是什么。
此外,还有与酸洗扩展类型相关的其他条目:

那么,所有这些与 Numpy 数组有什么关系:

  1. Numpy 数组是否实现特殊方法,例如 __reduce__ 来通知 Python 如何腌制它们(或 copyreg)? Numpy 对象仍然公开了一个 __reduce__ 方法,但这可能是出于兼容性原因。
  2. Numpy 是否使用 Pickle 开箱即用支持的 Python 的 C-API 结构(如新的 buffer protocol),因此不需要任何补充腌制 numpy 数组?

Python3pickle还是supports __reduce__, it is covered under the Pickling Class Instances section.

Numpy的支持在这方面没有改变;它在数组上实现 __reduce__ 以支持 Python 2 或 3:

中的 pickling
>>> 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__().

的状态元组