Выражения типов оцениваются статически с помощью средства проверки типов. * Сложные выражения, такие как type(f)
, не гарантированно работают, поскольку type(f)
соответствует типу runtime типа f
, а не его статически.аннотированное значение. ** Средство проверки типов не знает, каким будет этот тип времени выполнения.В общем, для максимальной совместимости вы должны придерживаться выражений типа, описанных в PEP 484 .
Часть проблемы здесь заключается в том, что decorate
не набирается вручную и неправильноВывод.
Так что исправьте.Например, можно сказать, что он возвращает объект того же типа, что и его аргумент:
T = typing.TypeVar('T')
d = typing.cast(typing.Callable[[T], T], decorate)
v = d(f) # v is inferred to have the same type as f
* Выражения типа также оцениваются во время выполнения, сохраняются в поле __annotations__
, а затемникогда не использовать снова, если какой-то код не решит проанализировать их.Эта функциональность во время выполнения используется редко и не имеет отношения к вопросу.
** На самом деле это еще хуже, потому что кто-то мог по-обезьянски пропатчить ваш модуль с помощью пользовательского type()
, который делает что-то совершенно отличное от встроенного.