TypeVar(A, B, covariant=True) 是什么意思?

问题描述 投票:0回答:1

今天我深入研究了里氏替换原理和协变/逆变。

我陷入了以下两者之间的区别:

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

我对#1的理解

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

这个答案清楚地表明了

T
可以是:

  1. Union[A, B]
    (或
    A
    B
    的任何子类型的联合,例如
    Union[A, BChild]
  2. A
    (或
    A
    的任何子类型)
  3. B
    (或
    B
    的任何子类型)

这对我来说非常有意义。


我对#2的有缺陷的理解

MyPy 不允许受约束的 TypeVar 是协变的?使用受约束但协变的键值类型定义通用字典

重新提到

bound=Union[A, B]
案例,但没有理解选项#2的含义,
A, B, covariant=True

我尝试过使用

mypy
,但似乎无法弄清楚。 谁能指出这是什么意思?

认为这意味着:

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

(也就是排除上面的

Union
情况)


**编辑**

评论里有人问:

你确定它们真的不同吗?

这是显示差异的示例代码。 错误来自

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) 中询问了这个问题,并传递了 A 的子类

这消除了我的一些误解。 事实证明

TypeVar("T", A, B, covariant=True)
并不真正正确,因为知道值限制
A
B
实际上并不是协变的。

使用

covariant=True
语法仅在它们相关时才有用。

python python-typing mypy covariance
1个回答
105
投票

协变和逆变是与面向对象和泛型之间的交集相关的术语。

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

  1. 我们有几个“常规”、“面向对象”类,
    Base
    Derived
  2. 我们还有一些通用类型 - 比如说
    List[T]
  3. 我们知道
    Derived
    可以在任何
    Base
    可以使用的地方使用 - 这是否意味着
    List[Derived]
    可以在任何
    List[Base]
    可以使用的地方使用?
  4. 有没有可能反过来呢?也许方向相反,现在
    List[Base]
    可以用在任何
    List[Derived]
    可以用的地方?

如果(3)的答案是肯定的,则称为 协方差,我们会说声明

List
具有
covariance=True
。如果 (4) 的答案为真,则称为 contra-variance。如果没有一个为真,则它是不变

界限也来自面向对象和泛型的交集。当我们定义泛型类型

MyType<T>
时,是否意味着
T
可以是任何类型?或者,我可以对
T
施加一些限制吗?边界允许我声明
T
的上限是,例如,类
Derived
。在这种情况下,
Base
不能与
MyType
一起使用 - 但
Derived
及其所有子类可以。

协变和逆变的定义可以在PEP-484的这一部分找到。

© www.soinside.com 2019 - 2024. All rights reserved.