Я думаю, что это уже спрашивали, но я не могу найти это

Как можно проверить наличие не встроенных типов в Python 3.6?

Например, допустим, я хочу иметь функцию foo (), которая принимает массив numy в качестве аргумента и возвращает экземпляр моего класса Bah

def foo(a: np.array) -> Bah

Могу ли я сделать что-то подобное? Как добавить эти типы для проверки?

3
opus111 20 Авг 2018 в 18:22

3 ответа

Лучший ответ

Вы можете указать все, что захотите, в качестве аннотации типа, если имя типа находится в области (например, вы определили Bob в текущем файле или сделали from stuff import Bob`).

В общем, средство проверки типов не требует специальных знаний о типе, чтобы узнать, является ли значение этим типом. Если он видит, вы сохраняете результат этой функции в переменной, тип которой Bob, или супертип Bob (который включает object и Any, а также включает аннотированный переменные), это законно; если он видит, что вы храните его в переменной с типом int или каком-либо другом несвязанном типе, это не так. Точно так же, если вы передаете результат какой-либо другой функции, чей параметр Bob или Any, или аннотированный, или вы добавляете его в List[Bob] и т. Д.

Но np.array это другая проблема. На самом деле это не тип, это просто функция конструктора, которая обычно возвращает значение типа np.ndarray, о котором вы обычно нигде не думаете. Таким образом, средство проверки типов не может справиться с этим без какой-либо специальной информации, которую array следует рассматривать как синоним ndarray.

Кроме того, многие функции NumPy - и, неявно, функции, которые вы пишете сами - на самом деле принимают «массив», который может быть ndarray или обычно matrix, но также часто любой последовательностью. В этом случае вы, вероятно, действительно хотите либо аннотировать, затем что-то более близкое к точному, например typing.Sequence - или, возможно, с пользовательским типом ArrayLike.

Несмотря на это, вы часто хотите указать тип dtype: ваша функция не хочет массив, она хочет массив с плавающей точкой или массив <something> и хочет вернуть {{X1 }} значения которого такие же <something>. Итак, вы, вероятно, хотите универсальный тип, такой как Sequence[float] или Sequence[T] для некоторого typevar T.

И вам может даже потребоваться определенное количество измерений, или даже форма для этих размеров, или даже форма частичная , или даже те параметры, которые x и y имеют быть транслируемым вместе или мультиплицируемым. Вы можете вставить эту информацию в общий тип, но вам придется тщательно ее продумать.

Во всяком случае, для ваших собственных типов, вам редко нужно думать так глубоко. Либо Bob является простым типом, которому нужны только стандартные правила наследования, поэтому вам не нужно ничего делать, либо это универсальный тип коллекции, где вам просто нужно наследовать / зарегистрировать его как {{X1} } или Mapping или что-то еще, и он автоматически получает соответствующие общие правила, или это определенный тип коллекции, где вы просто наследуете / регистрируетесь как Set[int], и он автоматически получает соответствующие правила.

4
abarnert 20 Авг 2018 в 15:44

Вы можете использовать печатать . Это библиотека Python https://docs.python.org/3/library/typing .html

import numpy as np
from bar import Bah
from typing import Type

def foo(a: np.ndarray): -> Type[Bah]
    return a.T  #example
1
SirSteel 20 Авг 2018 в 15:55

По сути, просто посмотрите на вывод типа (a), если вы знаете, что массив является пустым. Это скажет вам, что класс называется «numpy.ndarray». Затем проверьте это с помощью isinstance (). Как это:

import numpy #if you import numpy as np, you need to check for np.ndarray instead

def foo(a):
    if isinstance(a,numpy.ndarray):
        return Blah()
    else:
        print('a needs to be of type numpy.ndarray')
        return
0
LukasNeugebauer 20 Авг 2018 в 15:36
51933936