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

如何为np.recarray添加具体的类型注解?

关于numpy.recarray的Mypy类型标注问题

我在scratch.py中有以下代码:

import numpy as np

def my_array(arr: np.recarray) -> None:
    print(arr.x)

my_array(np.rec.array([(1.0, 2), (3.0, 4)], dtype=[('x', '<f8'), ('y', '<i8')]))

运行命令mypy scratch.py --disallow-any-generics后,出现如下错误:

scratch.py:3: error: Missing type parameters for generic type "recarray"  [type-arg]

用Any临时消除错误

以下代码可以规避上述错误,但类型标注不够精确:

def my_array(arr: np.recarray[Any, Any]) -> None:
    print(arr.x)

尝试更精确的类型标注(未成功)

我希望使用更具体的类型,比如这样的写法,但无法通过Mypy检查:

def my_array(arr: np.recarray[np.dtype[[('x', float), ('y', int)]]]) -> None:
    print(arr.x)

可通过检查但原理存疑的代码

下面这段代码能通过Mypy检查,但我不清楚原因:

from typing import Union

import numpy as np

def my_array(arr: np.recarray[Union[float, int], np.dtype[Union[np.float_, np.int_]]]) -> None:
    print(arr.x)

my_array(np.rec.array([(1.0, 2), (3.0, 4)], dtype=[('x', '<f8'), ('y', '<i8')]))

为什么这段代码能通过检查

np.recarray的泛型签名是recarray[ShapeType, DType]:

  • 第一个泛型参数ShapeType指代数组的形状类型(通常是整数元组,比如Tuple[int, int]表示二维数组),你写的Union[float, int]属于宽松写法,Mypy会将其视为兼容任意形状,不会触发错误
  • 第二个参数DType对应数组的 dtype,np.dtype[Union[np.float_, np.int_]]表示该 dtype 可以是浮点或整型,刚好匹配你定义的复合 dtype(包含float64和int64两种类型),因此Mypy判定类型兼容

更精确的标注方案

如果想要严格匹配你的结构化 dtype,可以用类型别名配合numpy.typing.NDArray(recarray本质上是NDArray的子类):

import numpy as np
from numpy.typing import NDArray
from typing import TypeAlias

# 定义对应结构化dtype的类型别名
MyRecordDtype: TypeAlias = np.dtype[
    [('x', np.float64), ('y', np.int64)]
]

def my_array(arr: NDArray[MyRecordDtype]) -> None:
    print(arr.x)

my_array(np.rec.array([(1.0, 2), (3.0, 4)], dtype=[('x', '<f8'), ('y', '<i8')]))

这样既符合Mypy的严格校验,又能精准标注输入的类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:25:21