Пытаюсь заставить PyCharm помочь мне проверить размеры массивов

#python #numpy #pycharm #type-hinting

#python #numpy #pycharm #подсказка типа

Вопрос:

Я пишу небольшую платформу реального анализа, которая будет работать с функциями на R ^ m, их производными, проекциями, функциями координат и т.д.

Я делаю это в PyCharm, и я хотел бы посмотреть, возможно ли, чтобы PyCharm помог мне убедиться, что у меня правильные размеры, когда я создаю новые функции или составляю / проект / дифференцирую / и т.д. Например, для функции из R ^ n в R ^ m якобиан должен быть mxn, и так далее.

Я пытаюсь использовать для этого подсказку типа. На данный момент я даже не пытаюсь получить np-массивы в схеме ввода, хотя это было бы неплохо, потому что входные и выходные данные для всего на самом деле имеют тип np.ndarray .

То, что я пробовал (простой пример см. Ниже), вообще не работает, PyCharm не жалуется в том месте, где я этого хочу. Я не знаю, возможно ли вообще что-либо подобное, но буду признателен за любые подсказки или совет.

 from abc import abstractmethod, ABC
from typing import TypeVar, Generic, NewType

import numpy as np

N = TypeVar("N")
M = TypeVar("M")
K = TypeVar("K")

NPVector = Generic[N]

# These other ways of doing it don't work either
#
# NPVector = NewType("NPVector", Generic[N])
#
# class NPVector(np.ndarray, Generic[N]):
#    pass


class VectorMapping(ABC, Generic[M, N]):

    @abstractmethod
    def apply(self, x: NPVector[M]) -> NPVector[N]:
        pass


class ComposedMapping(VectorMapping[M, N], Generic[M, N, K]):

    def __init__(self, first: VectorMapping[M, K], second: VectorMapping[K, N]):
        self.first = first
        self.second = second

    def apply(self, x: NPVector[M]) -> NPVector[N]:
        return self.second.apply(self.first.apply(x))

    def apply_wrong(self, x: NPVector[M]) -> NPVector[N]:
        # here is where I want PyCharm to complain
        return self.first.apply(self.second.apply(x))
  

Комментарии:

1. Почему бы просто не проверить размеры в начале функций? numpy функции делают это постоянно.

2. Да, я делаю это, но я хочу иметь возможность обнаруживать больше ошибок во время кодирования, а не во время выполнения.

3. Как pycharm (или что вообще) во время кодирования предполагается проверять размеры массива? Размеры массива задаются его shape и ndim свойствами. По общему признанию, я только type-hinting бегло взглянул, так что могут быть хитрости, о которых я не знаю.

4. @hpaulj PyCharm использует свою собственную реализацию linter… В некоторых других языках линтеры проверяют размеры массива. Я не уверен, но по памяти я не помню, чтобы в 484 сериях peps что-либо говорилось о размерах массива… Это интересный вопрос.

5. @hpaulj Много информации об измерениях и даже содержимом массивов доступно во время компиляции (или «во время IDE»). Например. если x это матрица, и мы вычисляем y=x.T@x , то во время компиляции мы знаем, что y это матрица, y она квадратная, y симметричная и y положительно (полу) определенная.