Spec-Zone.ru › NumPy 1.21

Типизация (numpy.typing)

Предупреждение

Некоторые типы в этом модуле полагаются на возможности, присутствующие только в стандартной библиотеке Python 3.8 и выше. Если вы хотите использовать эти типы в более ранних версиях Python, вы должны установить пакет typing-extensions.

Большая часть API NumPy содержит аннотации типов в стиле PEP-484. Кроме того, пользователям доступно несколько псевдонимов типов, в первую очередь два нижеперечисленных:

  • ArrayLike: объекты, которые можно преобразовать в массивы
  • DTypeLike: объекты, которые можно преобразовать в типы данных

Плагин Mypy

Плагин mypy распространяется в numpy.typing для управления несколькими платформа-специфическими аннотациями. Его функция может быть разделена на две части:

  • Назначение (зависимых от платформы) точностей определённых подклассов number, включая такие, как int_, intp и longlong. См. документацию по скалярным типам для обзора затронутых классов. Без плагина точность всех соответствующих классов будет выведена как Any.
  • Удаление всех подклассов number с расширенной точностью, недоступных для данной платформы. Наиболее заметно, это включает в себя такие типы, как float128 и complex256. Без плагина все типы с расширенной точностью, по мнению mypy, будут доступны на всех платформах.

Чтобы включить плагин, необходимо добавить его в свой файл конфигурации mypy .

[mypy]
plugins = numpy.typing.mypy_plugin

Отличия от 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 во время статической проверки типов.

Массивы размерности 0

Во время выполнения NumPy агрессивно преобразует все массивы размерности 0 в соответствующие экземпляры generic. До появления типизации форм (см. PEP 646) к сожалению, невозможно сделать необходимое различие между массивами размерности 0 и >0. Хотя это не строго верно, все операции, которые потенциально могут выполнить преобразование массива размерности 0 в скаляр, в настоящее время аннотированы как возвращающие исключительно ndarray.

Если заранее известно, что операция _будет_ выполнять преобразование массива размерности 0 в скаляр, то можно рассмотреть возможность ручного исправления ситуации, либо с помощью typing.cast, либо с помощью комментария # type: ignore.

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.

Среди прочих, это включает в себя:

  • type объекты.
  • Символьные коды или имена type объектов.
  • Объекты с атрибутом .dtype.

См. также

Указание и построение типов данных

Полноценный обзор всех объектов, которые можно привести к типам данных.

Примеры

>>> import numpy as np
>>> import numpy.typing as npt

>>> def as_dtype(d: npt.DTypeLike) -> np.dtype:
...     return np.dtype(d)
numpy.typing.NDArray = numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]][source]

Обобщенная версия np.ndarray[Any, np.dtype[+ScalarType]].

Можно использовать во время выполнения для типизации массивов с заданным типом данных и неопределённой формой.

Примеры

>>> import numpy as np
>>> import numpy.typing as npt

>>> print(npt.NDArray)
numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]

>>> print(npt.NDArray[np.float64])
numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

>>> NDArrayInt = npt.NDArray[np.int_]
>>> a: NDArrayInt = np.arange(10)

>>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
...     return np.array(a)
END_OF_DOCUMENT_MARKER
final class numpy.typing.NBitBase[source]

Объект, представляющий numpy.number точность во время статической проверки типов.

Используется исключительно для статической проверки типов, NBitBase представляет основу иерархического набора подклассов. Каждый последующий подкласс используется для представления более низкого уровня точности, например 64Bit > 32Bit > 16Bit.

Примеры

Ниже приведен типичный пример использования: NBitBase используется для аннотации функции, которая принимает число с плавающей точкой и целое число произвольной точности в качестве аргументов и возвращает новое число с плавающей точкой с наибольшей точностью (например np.float16 + np.int64 -> np.float64).

>>> from __future__ import annotations
>>> from typing import TypeVar, Union, TYPE_CHECKING
>>> import numpy as np
>>> import numpy.typing as npt

>>> T1 = TypeVar("T1", bound=npt.NBitBase)
>>> T2 = TypeVar("T2", bound=npt.NBitBase)

>>> def add(a: np.floating[T1], b: np.integer[T2]) -> np.floating[Union[T1, T2]]:
...     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–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/reference/typing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API