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

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

今天我深入研究了Liskov的替换原理和covariancecontravariance。

而我被这两者的区别卡住了。

  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] (或任何子类型的组合) 。AB 诸如 Union[A, BChild])
  2. A (或任何子类型的 A)
  3. B (或任何子类型的 B)

这对我来说很有意义。


我的 漏洞百出 对#2的理解

MyPy不允许约束的TypeVar是共价的?定义一个有约束但共变的键值类型的通用dict。

再次提及 bound=Union[A, B] 的情况下,但并没有得到选项2的意义。A, B, covariant=True.

我试着玩了一下 mypy但似乎搞不清楚。 谁能指出这是什么意思?

I 认为 它的意思是。

  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**

我最终在 pythonmypy #8806: 当T_co = TypeVar("T_co", A, B, covariant=True)并传递A的子类时,Generic[T_co]出错。

这澄清了我的一些误解。 原来 TypeVar("T", A, B, covariant=True) 其实并不正确,要知道价值的局限性 AB 其实并不是共变的。

使用 covariant=True 语法只有在它们相关的时候才有帮助。

python oop covariance typing static-typing
1个回答
3
投票

协方差和反方差是涉及到对象取向和属相之间的交集的术语。

这就是这个概念要回答的问题。

  1. 我们有几个 "常规","面向对象 "的类。BaseDerived.
  2. 我们也有一些通用类型--比方说 List<T>.
  3. 我们知道Derived可以在任何base可以使用的地方使用--这是否意味着 List<Derived> 哪儿都能用 List<Base> 可以吗?
  4. 会不会是反方向?也许是反方向,现在 List<Base> 随处可见 List<Derived> 可以吗?

如果(3)的答案是肯定的,那就叫协方差,我们就说声明吧 List 视为 covariance=True. 如果(4)的答案为真,就叫'反变性'。如果都不为真,就是不变性。

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

协方差和反方差的定义可以在下面找到。PEP-484的这一部分.

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