Сообщить об ошибке.

Определение универсальных функций в Python

Аннотация универсальных функций объявляются следующим образом:

Новое в 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.