Python类型TypeVar(A,B,convarant=True)是什么意思?

2024-09-29 02:28:48 发布

您现在位置:Python中文网/ 问答频道 /正文

今天我深入研究了利斯科夫的替代原理和协方差/逆变换

我被以下两者的区别所困扰:

  1. T = TypeVar("T", bound=Union[A, B])
  2. T = TypeVar("T", A, B, covariant=True)

我对#1的理解

Difference between TypeVar('T', A, B) and TypeVar('T', bound=Union[A, B])

This answer明确指出T可以是:

  1. Union[A, B] (or a union of any subtypes of A and B such as Union[A, BChild])
  2. A (or any subtype of A)
  3. B (or any subtype of B)

这对我来说很有意义


我对#2的理解有缺陷

MyPy doesn't allow constrained TypeVar's to be covariant? Defining a generic dict with constrained but covariant key-val types

再次提到了bound=Union[A, B]案例,但没有理解选项2 A, B, covariant=True的含义

我试过玩弄mypy,但似乎弄不明白。 有人能指出这是什么意思吗?

我认为这意味着:

  1. A(或A的任何亚型)
  2. B(或B的任何亚型)

(也就是说,它排除了上述Union案例)


**编辑**

评论中有人问:

Are you sure that they're actually different?

下面是显示差异的示例代码。错误来自mypy==0.770

from typing import Union, TypeVar, Generic


class A: pass

class ASub(A): pass

class B: pass


# Case 1... Success: no issues found
# T = TypeVar("T", bound=Union[A, B])

# Case 2... error: Value of type variable "T" of "SomeGeneric" cannot be "ASub"
T = TypeVar("T", A, B, covariant=True)


class SomeGeneric(Generic[T]): pass

class SomeGenericASub(SomeGeneric[ASub]): pass

**编辑2**

我最后在python/mypy #8806: Generic[T_co] erroring when T_co = TypeVar("T_co", A, B, covariant=True) and passed subclass of A问了这个问题

这消除了我的一些误解。事实证明TypeVar("T", A, B, covariant=True)并不正确,因为知道值限制AB实际上并不协变

使用covariant=True语法只有在它们相关时才有用


Tags: orandoftrueanypassgenericclass
1条回答
网友
1楼 · 发布于 2024-09-29 02:28:48

协方差和反方差是与对象定向和泛型之间的交集相关的术语

这是这个概念试图回答的问题:

  1. 我们有两个“常规的”、“面向对象的”类,BaseDerived
  2. 我们还有一些泛型类型,比如说List<T>
  3. 我们知道派生可以在base可以使用的任何地方使用-这是否意味着List<Derived>可以在List<Base>可以使用的任何地方使用
  4. 可能是另一种情况吗?也许是相反的方向,现在List<Base>可以在任何地方使用List<Derived>

如果(3)的答案是肯定的,它被称为协方差,我们将说List声明为covariance=True。如果(4)的答案为真,则称为“反向方差”。如果没有一个是真的,它是不变的

边界也来自OO和泛型的交叉点。当我们定义泛型类型MyType时,是否意味着“T”可以是任何类型?或者,我可以对T的可能形式施加一些限制吗?边界允许我声明T的上界是,例如,类Derived。在这种情况下,Base不能与'MyType'一起使用,但是Derived及其所有子类都可以

协方差和反方差的定义见this section of PEP-484

相关问题 更多 >