Одна из лучших вещей в Python - утка, набирающая , и Numpy в целом очень совместим с этим подходом к дизайну.Скажем, у вас есть только векторная функция vecfunc
.Вы можете добавить шаблон в начало функции, которая будет раздувать любые одномерные массивы в 1 x n
векторов:
def vecfunc(arr):
if arr.ndim==1:
arr = arr[None, :]
...function body goes here...
Это позволит избежать каких-либо проблем из-за arr
, имеющего слишком мало измерений, и, вероятно,по-прежнему дают правильное поведение в большинстве случаев.Однако это не делает ничего, чтобы предотвратить передачу пользователем, скажем, массива r x n x m
или массива 15 x n
.В конечном счете, вам придется пойти с подходом 3.
для множества этих вещей и просто выбросить некоторые исключения, где это кажется уместным.Например:
def vecfunc(arr):
if not 0 < arr.ndim < 3:
raise ValueError("arr must have ndim of 1 or 2. arr.ndim: %d" % arr.ndim)
elif arr.ndim==1:
arr = arr[None, :]
Если вам от этого станет легче, базы кодов numpy
и scipy
имеют такие формы:основанные проверки исключений в ряде функций, когда и где они необходимы.
Конечно, вы всегда можете прекратить добавлять такие виды проверок исключений до самого конца разработки любой данной функции.Вы можете быть удивлены диапазоном ввода, обеспечивающим разумное поведение.
Если вы не можете использовать аннотации типов, вы можете получить нечто подобное, написав свой код с использованием Cython .Например, если вам нужна функция add
, которая принимает только двумерные целочисленные массивы, вы можете написать следующую функцию в файле .pyx
:
import numpy as np
def add(long[:, :] arr1, long[:, :] arr2):
assert tuple(arr1.shape) == tuple(arr2.shape)
result = np.zeros((arr1.shape[0], arr1.shape[1]), dtype=np.long)
cdef long[:, :] result_view = result
for x in range(arr1.shape[0]):
for y in range(arr1.shape[1]):
result_view[x, y] = arr1[x, y] + arr2[x, y]
return result
Для получения дополнительной информации о написании и компиляции Cython см.Документы, ссылки на которые приведены выше.
Это не столько "аннотации типов", сколько настоящие строгие наборы, но может делать то, что вы хотите.К сожалению, я не смог найти способ зафиксировать размер одного измерения, только общее количество измерений.