ndarray.__new__ 如何知道它是从哪里被调用的?

问题描述 投票:0回答:1

在子类化 ndarray 的 numpy 文档中这里。据说

ndarray.__new__
,传递
__array_finalize__
我们自己的新对象 类 (
self
) 以及从中获取视图的对象 (
obj
).

我知道

ndarray.__new__
可以创建新对象
self
并将其传递给
__array_finalize__
,但是它如何从调用的地方获取
obj
呢?从
ndarray.__new__
的签名来看,看起来
obj
没有从调用函数传递。那么
ndarray.__new__
是否使用一些深层魔法(可能在 C 级别)来确定调用它的位置(即构造函数调用、视图转换或从模板中新建)?

numpy multidimensional-array numpy-ndarray subclassing
1个回答
0
投票

TL:DR:这是

buffer
np.ndarray.__new__(...)
参数。有关子类化的 numpy 文档讨论了创建新对象、视图和新模板。它们向您展示了如何从头开始创建子类的新对象
MySubClass(...)
和子类的视图对象
arr.view(MySubClass)
,但它们不向您展示如何创建子类的新模板,除了提到它发生在切片中。

您可以通过以下方式查看:

import numpy as np

arr = 2 * np.ones(3)
np.ndarray.__new__(np.ndarray, shape=(1,), dtype=float, buffer=arr)

给出

array([2.])
。显然,对象模板作为缓冲区传递,因此步幅、顺序、形状、数据类型等因素会影响
arr
中数据的解释方式。

正如 @tim-roberts 指出的,

InfoArray
示例很有帮助,实际上包含完整的调用签名。我自己找不到它,可能是因为 numpy._core.__init__.pyi 故意留空。尽管如此,类型检查器确实找到了完整的签名:

(cls: type[_ArraySelf@__new__], shape: _ShapeLike,
dtype: DTypeLike = ..., buffer: _SupportsBuffer | None = ...,
offset: SupportsIndex = ..., strides: _ShapeLike | None = ...,
order: _OrderKACF = ...) -> _ArraySelf@__new__

我的用例,因为蒂姆问:我的子类带有引用轴定义的属性(例如

arr.ax_time
),以便使一些数学更清晰(例如
differentiate(arr, axis=arr.ax_time)
)。这意味着
ndarray.view(MyClass)
没有多大意义,所以我想修改使用标准视图的示例测试 (test_ufunc_override_with_super) 来改为使用 new-from-template 。

© www.soinside.com 2019 - 2024. All rights reserved.