TypeError:“numpy._DTypeMeta”对象不可订阅

vojdkbi0  于 2023-10-19  发布在  其他
关注(0)|答案(4)|浏览(145)

我试着像这样输入一个numpy ndarray

RGB = numpy.dtype[numpy.uint8]
ThreeD = tuple[int, int, int]

def load_images(paths: list[str]) -> tuple[list[numpy.ndarray[ThreeD, RGB]], list[str]]: ...

但在第一行,当我运行这个,我得到了以下错误:

RGB = numpy.dtype[numpy.uint8]
TypeError: 'numpy._DTypeMeta' object is not subscriptable

如何正确输入hint ndarray

vof42yt1

vof42yt11#

pip install numpy==1.20.0

将致力

nfeuvbwi

nfeuvbwi2#

事实证明,强类型numpy数组并不简单。我花了几个小时来弄清楚如何正确地做到这一点。
一个简单的方法是使用here中描述的技巧,而不是向项目中添加另一个依赖项。只需使用' Package numpy类型:

import numpy
import numpy.typing as npt
from typing import cast, Type, Sequence
import typing

RGB: typing.TypeAlias = 'numpy.dtype[numpy.uint8]'
ThreeD: typing.TypeAlias = tuple[int, int, int]
NDArrayRGB: typing.TypeAlias = 'numpy.ndarray[ThreeD, RGB]'

def load_images(paths: list[str]) -> tuple[list[NDArrayRGB], list[str]]: ...

技巧是使用单引号,以避免在Python试图解释表达式中的[]时出现臭名昭著的TypeError: 'numpy._DTypeMeta' object is not subscriptable。例如,VSCode Pylance类型检查器可以很好地处理这个技巧:

请注意,类型的颜色是受尊重的,并且执行不会出错。

关于nptyping的说明

正如@ddejohn所建议的,可以使用nptyping。只需安装软件包:pip install nptyping。但是,截至目前(2022年6月16日),nptyping中没有定义Tuple类型,因此您无法以这种方式正确输入代码。我有open a new issue,所以也许在未来它会工作。
编辑次数
事实证明,有一种不同的方法可以将tuple表示为nptyping.Shape,正如ramonhagenaars所回答的那样,这也是优雅的:

from nptyping import NDArray, Shape, UInt8

# A 1-dimensional array (i.e. 1 RGB color).
RGBArray1D = NDArray[Shape["[r, g, b]"], UInt8]

# A 2-dimensional array (i.e. an array of RGB colors).
RGBArrayND = NDArray[Shape["*, [r, g, b]"], UInt8]

def load_images_trick(paths: list[str]) -> tuple[list[RGBArrayND], list[str]]: ...

然而,VSCode Pylance并不支持这个解决方案,我得到了Shape的错误建议:

Expected class type but received "Literal"
  "Literal" is not a class
  "Literal" is not a classPylancereportGeneralTypeIssues
Pylance(reportGeneralTypeIssues)

bsxbgnwa

bsxbgnwa3#

我的opencv2库也有类似的问题,我通过升级numpy pip install numpy --upgrade

c9x0cxw0

c9x0cxw04#

命令np.ndarray[...]会对某些版本的numpy引发异常。在接受的答案中使用的命令typing.TypeAlias也会对某些版本的python产生异常,例如。[ 1 ]。我在与使用不同操作系统和不同python版本的同事合作时遇到了这个问题。他们更新了numpy,但错误仍然存在,所以我想出了这个解决方案,对我们所有人都有效,并且仍然检查我机器中的类型错误:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from typing import TypeAlias
else:
    TypeAlias = "TypeAlias"

NDArrayInt: "TypeAlias" = "np.ndarray[int, np.dtype[np.number]]"
NDArrayFloat: "TypeAlias" = "np.ndarray[float, np.dtype[np.number]]"
DiscreteMechanism: "TypeAlias" = "Callable[[NDArrayInt], NDArrayInt]"

相关问题