如何输入提示通用 numpy 数组?

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

有什么方法可以将 Numpy 数组键入为通用数组吗?

我目前正在使用 Numpy 1.23.5 和 Python 3.10,我无法输入以下示例的提示。

import numpy as np
import numpy.typing as npt


E = TypeVar("E") # Should be bounded to a numpy type

def double_arr(arr: npt.NDArray[E]) -> npt.NDArray[E]:
    return arr * 2

我所期待的

arr = np.array([1, 2, 3], dtype=np.int8)
double_arr(arr) # npt.NDAarray[np.int8]

arr = np.array([1, 2.3, 3], dtype=np.float32)
double_arr(arr) # npt.NDAarray[np.float32]

但是我最终遇到了以下错误

arr: npt.NDArray[E]
                ^^^
Could not specialize type "NDArray[ScalarType@NDArray]"
  Type "E@double_arr" cannot be assigned to type "generic"
    "object*" is incompatible with "generic"

如果我将 E 绑定到 numpy 数据类型 (

np.int8, np.uint8, ...
),由于存在多种数据类型,类型检查器无法评估乘法。

python numpy mypy python-typing
1个回答
7
投票

查看 source,似乎用于参数化

numpy.dtype
的泛型类型变量以
numpy.typing.NDArray
为界(并声明为协变)。因此
numpy.generic
的任何类型参数都必须是
NDArray
的子类型,而您的类型变量是无界的。这
应该
有效: numpy.generic

但是还有另一个问题,我认为这个问题在于 numpy 存根不足。 
本期

中展示了一个示例。像 from typing import TypeVar import numpy as np from numpy.typing import NDArray E = TypeVar("E", bound=np.generic, covariant=True) def double_arr(arr: NDArray[E]) -> NDArray[E]: return arr * 2 这样的重载操作数(魔术)方法会以某种方式破坏类型。我现在只是粗略地浏览了

代码
,所以我不知道缺少什么。但是 __mul__ 仍然会抱怨该代码中的最后一行:
错误:从声明为返回“ndarray [Any,dtype [E]]”的函数返回任何[无任何返回]
错误: * ("ndarray[Any, dtype[E]]" 和 "int") [运算符] 不支持的操作数类型

现在的解决方法是使用函数而不是操作数(通过 dunder 方法)。在这种情况下,使用 

mypy

 而不是 
numpy.multiply 可以解决问题:
*

不再有
from typing import TypeVar import numpy as np from numpy.typing import NDArray E = TypeVar("E", bound=np.generic, covariant=True) def double_arr(arr: NDArray[E]) -> NDArray[E]: return np.multiply(arr, 2) a = np.array([1, 2, 3], dtype=np.int8) reveal_type(double_arr(a))

投诉,类型揭露如下:

mypy

值得关注该操作数问题,甚至可能单独报告 
numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy._typing._8Bit]]]

的具体错误。我还没有在问题跟踪器中找到它。



PS

:或者,您可以使用 Unsupported operand types for * 运算符并添加

特定
*。这样你就会注意到,如果/一旦注释错误最终被 numpy 修复,因为
type: ignore
抱怨严格模式下未使用的忽略指令。
mypy

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