Python ›=3.5: Проверка аннотации типа во время выполнения

Есть ли в модуле typing (или любом другом модуле) API для проверки типов переменных во время выполнения, аналогичное isinstance(), но понимающее классы типов, определенные в typing?

Я хотел бы запустить что-то вроде:

from typing import List
assert isinstance([1, 'bob'], List[int]), 'Wrong type'

person Bertrand Caron    schedule 27.04.2017    source источник
comment
Нет, вы не можете, но здесь есть аналогичный вопрос: stackoverflow.com/questions/37973820/, и я попытался ответить на него.   -  person max    schedule 28.04.2017
comment
@max Спасибо за попытку. На самом деле я пытался связаться с mypy людьми через gitter, и похоже, что аналогичная функция находится в разработке, я посмотрю, смогу ли я найти кого-нибудь из проекта, чтобы ответить здесь, и, возможно, обновить его по мере продвижения.   -  person Bertrand Caron    schedule 28.04.2017
comment
Насколько я понимаю, typing_inspect — это не совсем то, что вы ищете; это больше касается проверки самих объектов типов.   -  person Elazar    schedule 28.04.2017
comment
В этом тесно связанном вопросе есть очень сложная реализация проверки типов: Проверка подробных типов в классах данных python   -  person Aran-Fey    schedule 03.10.2018
comment
Спасибо за это, похоже, в ответе достаточно кода, чтобы гарантировать небольшой (но очень полезный) пакет;)   -  person Bertrand Caron    schedule 05.10.2018


Ответы (2)


Я искал что-то подобное и нашел библиотеку typeguard. Это может автоматически выполнять проверки типов во время выполнения, где бы вы ни захотели. Также поддерживается проверка типов напрямую, как в вопросе. Из документов,

from typeguard import check_type

# Raises TypeError if there's a problem
check_type('variablename', [1234], List[int])
person aravindsagar    schedule 05.09.2019
comment
Еще лучше то, что декоратор typeguard @typechecked позволяет автоматически выполнять проверку подсказки типа для всех входных и выходных данных функции. Или, если вы добавите его в определение класса, он будет выполнять проверку во время выполнения для всех своих методов. - person crypdick; 20.10.2020

В модуле typing такой функции нет и скорее всего не будет.

Проверка того, является ли объект экземпляром класса, что означает только то, что "этот объект был создан конструктором класса" - это простой вопрос проверки некоторых тегов.

Однако проверка того, является ли объект «экземпляром» типа, не обязательно разрешима:

assert isinstance(foo, Callable[[int], str]), 'Wrong type'

Хотя легко проверить типизированные аннотации foo (при условии, что это не lambda), проверка соответствия им, как правило, неразрешима по теореме Райса.

Даже с более простыми типами, такими как List[int], тест легко станет слишком неэффективным, чтобы его можно было использовать для чего-либо, кроме самых маленьких игрушечных примеров.

xs = set(range(10000))
xs.add("a")
xs.pop()
assert isinstance(xs, Set[int]), 'Wrong type'

Трюк, который позволяет программе проверки типов выполнять эту операцию относительно эффективно, заключается в том, чтобы быть консервативным: программа проверки типов пытается доказать, что foo всегда возвращает int. В случае сбоя он отвергает программу, даже если программа может быть валидной, т.е. эта функция, скорее всего, будет отклонена, хотя она совершенно безопасна:

def foo() -> int:
    if "a".startswith("a"):
        return 1
    return "x"
person Elazar    schedule 28.04.2017
comment
Да. В ответе на аналогичный вопрос я тоже пришел к такому выводу (хотя эти абзацы я удалил, потому что мое объяснение показалось мне не очень ясным). Я думаю, что система типов python typing/PEP 484 построена для статической проверки типов и не подходит для динамической проверки типов. Практически полезную динамическую систему типов можно построить, но она будет сильно отличаться (в основном намного проще), чем PEP 484. И, возможно, довольно хороший уже включен в ваш готовый интерпретатор Python. - person max; 28.04.2017
comment
В модуле набора текста такой функции нет и скорее всего никогда не будет. -- упс! - person Noldorin; 08.03.2021