Аннотация универсальных функций объявляются следующим образом:
Новое в Python 3.12.
def func[T](arg: T): ...
Этот синтаксис эквивалентен:
annotation-def TYPE_PARAMS_OF_func(): T = typing.TypeVar("T") def func(arg: T): ... func.__type_params__ = (T,) return func func = TYPE_PARAMS_OF_func()
Здесь определение annotation-def
(не реальное ключевое слово) указывает на область видимости аннотации, которая фактически не привязана ни к какому имени во время выполнения. (Синтаксис не проходит через доступ к атрибутам модуля typing
, а создает экземпляр typing.TypeVar
напрямую.)
Аннотации универсальных функций оцениваются в пределах области видимости аннотаций, используемой для объявления параметров типа, но по умолчанию функции и декораторы не являются таковыми.
Следующий пример иллюстрирует правила определения области видимости для этих случаев, а также для дополнительных вариантов параметров типа:
@decorator def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = some_default): ...
За исключением ленивой оценки привязки typing.TypeVar
, это эквивалентно:
DEFAULT_OF_arg = some_default annotation-def TYPE_PARAMS_OF_func(): annotation-def BOUND_OF_T(): return int # `BOUND_OF_T()` оценивается только по требованию. T = typing.TypeVar("T", bound=BOUND_OF_T()) Ts = typing.TypeVarTuple("Ts") P = typing.ParamSpec("P") def func(*args: *Ts, arg: Callable[P, T] = DEFAULT_OF_arg): ... func.__type_params__ = (T, Ts, P) return func func = decorator(TYPE_PARAMS_OF_func())
Имена с заглавной буквы, такие как DEFAULT_OF_arg
, фактически не привязываются во время выполнения.
Новое в Python 3.12.