gpt4 book ai didi

python - TypeVar ('T' , A, B) 和 TypeVar ('T' 之间的区别,bound=Union[A, B])

转载 作者:行者123 更新时间:2023-12-03 16:42:55 25 4
gpt4 key购买 nike

我正在努力理解以下两个 TypeVar 之间的区别年代:

from typing import TypeVar, Union

class A: pass
class B: pass

T = TypeVar("T", A, B)
T = TypeVar("T", bound=Union[A, B])
有人想开导我吗?

作为我不明白的一个例子:这通过了类型检查......
T = TypeVar("T", bound=Union[A, B])

class AA(A):
pass


class X(Generic[T]):
pass


class XA(X[A]):
pass


class XAA(X[AA]):
pass
...但与 T = TypeVar("T", A, B) ,它失败了

error: Value of type variable "T" of "X" cannot be "AA"



相关: this question关于 Union[A, B] 之间的区别和 TypeVar("T", A, B) .

最佳答案

当你这样做 T = TypeVar("T", bound=Union[A, B]) ,你是说 T 可以绑定(bind)到 Union[A, B]Union[A, B] 的任何子类型.它是联合的上限。

例如,如果你有一个类型为 def f(x: T) -> T 的函数。 ,传入以下任何类型的值都是合法的:

  • Union[A, B] (或 A 和 B 的任何子类型的联合,例如 Union[A, BChild] )
  • A (或 A 的任何亚型)
  • B (或 B 的任何亚型)

  • 这就是泛型在大多数编程语言中的行为方式:它们允许您强加一个上限。

    但是当你这样做 T = TypeVar("T", A, B) ,你基本上是在说 T必须以 A 为上限或以 B 为上限。也就是说,您可以建立多个上限,而不是建立单个上限!

    所以这意味着虽然传入任一类型的值都是合法的 AB进入 f , 传入 Union[A, B] 是不合法的因为联合既不是 A 也不是 B 的上限。

    例如,假设您有一个可包含 int 或 strs 的可迭代对象。

    如果你希望这个迭代包含任意整数或字符串的混合,你只需要一个 Union[int, str] 的上界。 .例如:

    from typing import TypeVar, Union, List, Iterable

    mix1: List[Union[int, str]] = [1, "a", 3]
    mix2: List[Union[int, str]] = [4, "x", "y"]
    all_ints = [1, 2, 3]
    all_strs = ["a", "b", "c"]


    T1 = TypeVar('T1', bound=Union[int, str])

    def concat1(x: Iterable[T1], y: Iterable[T1]) -> List[T1]:
    out: List[T1] = []
    out.extend(x)
    out.extend(y)
    return out

    # Type checks
    a1 = concat1(mix1, mix2)

    # Also type checks (though your type checker may need a hint to deduce
    # you really do want a union)
    a2: List[Union[int, str]] = concat1(all_ints, all_strs)

    # Also type checks
    a3 = concat1(all_strs, all_strs)

    相反,如果您想强制该函数接受所有 int 或所有 str 的列表,但绝不接受两者的混合,则需要多个上限。

    T2 = TypeVar('T2', int, str)

    def concat2(x: Iterable[T2], y: Iterable[T2]) -> List[T2]:
    out: List[T2] = []
    out.extend(x)
    out.extend(y)
    return out

    # Does NOT type check
    b1 = concat2(mix1, mix2)

    # Also does NOT type check
    b2 = concat2(all_ints, all_strs)

    # But this type checks
    b3 = concat2(all_ints, all_ints)

    关于python - TypeVar ('T' , A, B) 和 TypeVar ('T' 之间的区别,bound=Union[A, B]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59933946/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com