В чем разница между ограниченным TypeVar и Union?

Если я хочу иметь тип, который может быть несколькими возможными типами, Unions, похоже, то, как я это представляю:

U = Union[int, str] 

U может быть int или str.

Я заметил, что TypeVars допускает необязательные аргументы var-arg, которые, похоже, делают то же самое:

T = TypeVar("T", int, str)

И T, и U, похоже, могут принимать только типы str и int.

В чем разница между этими двумя способами и когда следует отдавать предпочтение каждому из них?


person Carcigenicate    schedule 17.11.2019    source источник
comment


Ответы (1)


Тип T должен быть согласован для нескольких применений в пределах заданного область, а U - нет.

Если в качестве параметров функции используется тип Union, аргументы, а также возвращаемый тип могут быть разными:

U = Union[int, str]

def union_f(arg1: U, arg2: U) -> U:
    return arg1

x = union_f(1, "b")  # No error due to different types
x = union_f(1, 2)  # Also no error
x = union_f("a", 2)  # Also no error
x # And it can't tell in any of the cases if 'x' is an int or string

Сравните это с аналогичным случаем с TypeVar, где типы аргументов должны совпадать:

T = TypeVar("T", int, str)

def typevar_f(arg1: T, arg2: T) -> T:
    return arg1

y = typevar_f(1, "b")  # "Expected type 'int' (matched generic type 'T'), got 'str' instead
y = typevar_f("a", 2)  # "Expected type 'str' (matched generic type 'T'), got 'int' instead

y = typevar_f("a", "b")  # No error
y  # It knows that 'y' is a string

y = typevar_f(1, 2)  # No error
y  # It knows that 'y' is an int

Итак, используйте TypeVar, если разрешено несколько типов, но разные варианты использования T в одной области должны соответствовать друг другу. Используйте Union, если разрешено несколько типов, но различное использование U в рамках данной области не обязательно должно соответствовать друг другу.

person Carcigenicate    schedule 17.11.2019
comment
Может ли кто-нибудь уточнить значение слова в рамках одной области в этом контексте? В частности, если я являюсь внешней областью (модуль, класс или что-то еще), и я объявляю TypeVar, и я использую этот тип в двух разных функциях, должно ли использование var соответствовать двум внутренним областям (функциям) по отдельности или по всему внешнему прибору? Что делать, если у меня есть вложенные функции? - person ShapeOfMatter; 21.04.2020
comment
@ShapeOfMatter Обратите внимание на часть PEP, с которой я связался вверху. Он входит в довольно глубокие детали. - person Carcigenicate; 21.04.2020
comment
@ShapeOfMatter Если T определен вне каких-либо функций, его тип может различаться для разных функций, если только эти функции не являются методами, и класс, который их включает, Generic на T. - person Carcigenicate; 21.04.2020