Python — это просьба о прощении, а не о разрешении. Это означает, что даже в вашем первом определении def foo(x: np.ndarray, y: float):
действительно полагается на то, что пользователь примет подсказку, если только вы не используете что-то вроде mypy.
Есть несколько подходов, которые вы можете использовать здесь, обычно в тандеме. Один из них — написать функцию таким образом, чтобы она работала с переданными входными данными, что может означать сбой или принуждение к недопустимым входным данным. Другой метод заключается в тщательном документировании вашего кода, чтобы пользователи могли принимать разумные решения. Второй способ особенно важен, но я остановлюсь на первом.
Numpy делает большую часть проверки за вас. Например, вместо того, чтобы ожидать массив, идиоматично принуждать его:
x = np.asanyarray(x)
np.asanyarray
обычно является псевдонимом для array(a, dtype, copy=False, order=order, subok=True)
. Вы можете сделать что-то подобное для y
:
y = np.asanyarray(y).item()
Это позволит использовать любой массив, если он имеет один элемент, скалярный или нет. Другой способ - уважать способность numpy транслировать массивы вместе, поэтому, если пользователь передает y
как список из x.shape[-1]
элементов.
Для вашей второй функции у вас есть несколько вариантов. Один из вариантов — разрешить причудливую индексацию. Поэтому, если пользователь передает список индексов вместо логической маски, вы можете использовать оба. Если, с другой стороны, вы настаиваете на логической маске, вы можете либо проверить, либо принудить dtype.
Если вы проверите, имейте в виду, что операция индексации numpy вызовет для вас ошибку, если размеры массива не совпадают. Вам нужно только проверить сам тип:
points = np.asanyarray(points)
valid = np.asanyarray(valid)
if valid.dtype != bool:
raise ValueError('valid argument must be a boolean mask')
Если вместо этого вы выберете принуждение, пользователю будет разрешено использовать нули и единицы, но действительные входные данные не будут копироваться без необходимости:
valid = np.asanyarray(valid, bool)
person
Mad Physicist
schedule
28.01.2021
valid.dtype == bool
? - person juanpa.arrivillaga   schedule 28.01.2021mypy
? IDE? - person hpaulj   schedule 28.01.2021tags
. - person hpaulj   schedule 28.01.2021numpy
проверяют такие вещи, как размеры и dtype, чаще всего они просто пытаются преобразовать/принудить входные данные. Например, это может бытьx = np.asarray(x, dtype=float)
илиx = np.atleast_2d(x)
. - person hpaulj   schedule 28.01.2021dtype
которыхbool
. Я думаю, что многого можно ожидать от IDE. Если это предупреждение IDE действительно важно для вас, вы можете попробовать создать подклассnumpy
массиваbool
dtype
и определить свою функцию как принимающую массив вашего подкласса в качестве второго аргумента, а не массивnumpy
. Но это может быть излишним, потому что создание подклассов массивов numpy немного сложнее, чем создание подклассов классов Python. - person fountainhead   schedule 28.01.2021numpy
в свою функцию, с точки зрения Python (и, следовательно, с точки зрения PyCharm), независимо от того, имеет ли передаваемый массивbool
dtype
или какой-либо другойdtype
, он фиксируется в атрибутах. объекта, а не в типе объекта. Чтобы удовлетворить ваше требование, PyCharm должен будет проверить атрибуты объекта аргумента, чего, я думаю, слишком много, чтобы ожидать от IDE. - person fountainhead   schedule 28.01.2021True
иFalse
сbool
dtype
. Во время выполнения вы можете изменитьdtype
наint
, что по существу обойдёт все предупреждения IDE. Согласен, это был бы экстремальный сценарий, преднамеренный злой умысел программиста, а не ошибка программиста. - person fountainhead   schedule 28.01.2021