You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NumPy ndarray子类__array_wrap__运行结果与文档示例不一致

NumPy子类化示例输出与文档不符问题说明

这一现象是官方文档内容过时导致的,既不是NumPy版本bug,也不是你对方法的使用理解有遗漏。

核心原因

NumPy在1.17版本对ufunc的类型分派逻辑做了不兼容旧流程的调整,而1.23版本文档中该章节的示例输出没有同步更新,仍然沿用了1.16及更早版本的执行流程结果。

1.16及更早版本的执行流程(对应文档给出的预期输出)

  • 创建MySubClass实例时,np.asarray(...).view(cls)触发第一次__array_finalize__:self是新创建的子类实例,obj是原始普通ndarray,对应输出第一组打印。
  • ufuncnp.add执行计算时,先输出普通ndarray类型的计算结果,再调用子类的__array_wrap__方法,此时传入的out_arr是普通ndarray,对应文档中arr is array([1, 3, 5, 7, 9])的打印。
  • 父类__array_wrap__将普通ndarray结果转为子类实例时,触发第二次__array_finalize__:self是结果子类实例,obj是输入的子类实例,对应文档第三组打印。

1.17及之后版本的执行流程(对应你实际运行的输出)

  • 版本更新后新增__array_ufunc__作为ufunc分派的优先逻辑,基类默认实现会在ufunc计算开始前就提前将输出数组分配为对应子类类型,不再等计算完成后通过__array_wrap__做类型转换。
  • 创建子类实例触发的第一次__array_finalize__和旧版本完全一致。
  • ufunc准备输出数组阶段,为输出数组分配子类类型时触发第二次__array_finalize__:此时self是刚分配的输出子类实例(初始值和输入子类一致),obj是输入的子类实例,对应你运行结果中多出来的第二组打印。
  • ufunc计算完成后调用__array_wrap__时,传入的out_arr已经是提前分配好的子类实例,因此打印中arr显示为MySubClass类型。
  • 由于输出数组已经是子类类型,父类__array_wrap__不需要再做类型转换,也就不会触发旧流程中的第三次__array_finalize__。

补充说明

__array_wrap__目前仅作为兼容旧代码的接口保留,当前NumPy推荐子类自定义ufunc、函数行为时优先使用__array_ufunc__、__array_function__协议实现。

内容的提问来源于stack exchange,提问作者Wood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 19:54:16