What's the difference between a constrained TypeVar and a Union?

后端 未结 1 842
梦如初夏
梦如初夏 2020-11-30 08:13

If I want to have a type that can represent multiple possible types, Unions seem to be how I represent that:

U = Union[int, str] 
相关标签:
1条回答
  • 2020-11-30 08:50

    T's type must be consistent across multiple uses within a given scope, while U's does not.

    With a Union type used as function parameters, the arguments as well as the return type can all be different:

    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
    

    Compare that to a similar case with a TypeVar where the argument types must match:

    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
    

    So, use a TypeVar if multiple types are allowed, but different usages of T within a single scope must match each other. Use a Union if multiple types are allowed, but different usages of U within a given scope don't need to match each other.

    0 讨论(0)
提交回复
热议问题