Типизация (numpy.typing)
Предупреждение
Некоторые типы в этом модуле зависят от функций, присутствующих только в стандартной библиотеке Python 3.8 и выше. Если вы хотите использовать эти типы в более ранних версиях Python, необходимо установить пакет typing-extensions.
Большая часть API NumPy содержит аннотации типов в стиле PEP-484. Кроме того, доступно несколько псевдонимов типов, наиболее заметные из которых два ниже:
ArrayLike: объекты, которые могут быть преобразованы в массивыDTypeLike: объекты, которые могут быть преобразованы в типы данных
Отличия от API NumPy во время выполнения
NumPy очень гибкий. Попытка статически описать весь спектр возможностей приведет к типам, которые не будут очень полезными. По этой причине типизированный API NumPy часто строже, чем API NumPy во время выполнения. В этом разделе описаны некоторые заметные отличия.
ArrayLike
Тип ArrayLike старается избежать создания массивов объектов. Например,
>>> np.array(x**2 for x in range(10)) array(<generator object <genexpr> at ...>, dtype=object)
является допустимым кодом NumPy, который создаст массив объектов размерности 0. Однако средства проверки типов будут жаловаться на приведенный выше пример при использовании типов NumPy. Если вы действительно хотели сделать вышеперечисленное, то можно либо использовать комментарий # type: ignore,
>>> np.array(x**2 for x in range(10)) # type: ignore
либо явно указать тип объекта массива как Any:
>>> from typing import Any >>> array_like: Any = (x**2 for x in range(10)) >>> np.array(array_like) array(<generator object <genexpr> at ...>, dtype=object)
ndarray
Возможно изменение типа данных массива во время выполнения. Например, следующий код является допустимым:
>>> x = np.array([1, 2]) >>> x.dtype = np.bool_
Такого рода мутация не допускается типами. Пользователи, желающие писать статически типизированный код, должны вместо этого использовать метод numpy.ndarray.view для создания представления массива с другим типом данных.
DTypeLike
Тип DTypeLike старается избежать создания объектов типов данных с использованием словаря полей, как показано ниже:
>>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)})
Хотя это допустимый код NumPy, средство проверки типов будет жаловаться на него, поскольку его использование не рекомендуется. См. : Объекты типов данных
Точность чисел
Точность подклассов numpy.number обрабатывается как ковариативный параметр шаблона (см. NBitBase), что упрощает аннотирование процессов, включающих преобразования, основанные на точности.
>>> from typing import TypeVar
>>> import numpy as np
>>> import numpy.typing as npt
>>> T = TypeVar("T", bound=npt.NBitBase)
>>> def func(a: "np.floating[T]", b: "np.floating[T]") -> "np.floating[T]":
... ...
Следовательно, такие как float16, float32 и float64, по-прежнему являются подтипами floating, но, в отличие от выполнения, они не обязательно считаются подклассами.
Timedelta64
Класс timedelta64 не рассматривается как подкласс signedinteger, так как первый наследуется только от generic при проверке статического типа.
API
-
numpy.typing.ArrayLike = typing.Union[...] -
Union, представляющий объекты, которые можно привести кndarray.Включает, среди прочего:
- Скаляры.
- (Вложенные) последовательности.
- Объекты, реализующие протокол
__array__.
См. также
- array_like:
-
Любой скаляр или последовательность, которые можно интерпретировать как ndarray.
Примеры
>>> import numpy as np >>> import numpy.typing as npt >>> def as_array(a: npt.ArrayLike) -> np.ndarray: ... return np.array(a)
-
numpy.typing.DTypeLike = typing.Union[...] -
Union, представляющий объекты, которые можно привести кdtype.Включает, среди прочего:
См. также
- Указание и создание типов данных
-
Подробный обзор всех объектов, которые могут быть приведены к типам данных.
Примеры
>>> import numpy as np >>> import numpy.typing as npt >>> def as_dtype(d: npt.DTypeLike) -> np.dtype: ... return np.dtype(d)
-
class numpy.typing.NBitBase[source] -
Объект, представляющий точность
numpy.numberпри проверке статического типа.Используется исключительно для проверки статического типа,
NBitBaseпредставляет базу иерархического набора подклассов. Каждый последующий подкласс используется для представления более низкого уровня точности, например64Bit > 32Bit > 16Bit.Примеры
Ниже приведен типичный пример использования:
NBitBaseздесь используется для аннотации функции, которая принимает числа с плавающей запятой и целые числа произвольной точности в качестве аргументов и возвращает новое число с плавающей запятой с наибольшей точностью (напримерnp.float16 + np.int64 -> np.float64).>>> from typing import TypeVar, TYPE_CHECKING >>> import numpy as np >>> import numpy.typing as npt >>> T = TypeVar("T", bound=npt.NBitBase) >>> def add(a: "np.floating[T]", b: "np.integer[T]") -> "np.floating[T]": ... return a + b >>> a = np.float16() >>> b = np.int64() >>> out = add(a, b) >>> if TYPE_CHECKING: ... reveal_locals() ... # note: Revealed local types are: ... # note: a: numpy.floating[numpy.typing._16Bit*] ... # note: b: numpy.signedinteger[numpy.typing._64Bit*] ... # note: out: numpy.floating[numpy.typing._64Bit*]
© 2005–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/reference/typing.html