今天我深入研究了Liskov的替换原理和covariancecontravariance。
而我被这两者的区别卡住了。
T = TypeVar("T", bound=Union[A, B])
T = TypeVar("T", A, B, covariant=True)
我对#1的理解
TypeVar('T', A, B)和TypeVar('T', bound=Union[A, B])之间的区别。
这个答案 明确指出 T
可以是 。
Union[A, B]
(或任何子类型的组合) 。A
和B
诸如Union[A, BChild]
)A
(或任何子类型的A
)B
(或任何子类型的B
)
这对我来说很有意义。
我的 漏洞百出 对#2的理解
MyPy不允许约束的TypeVar是共价的?定义一个有约束但共变的键值类型的通用dict。
再次提及 bound=Union[A, B]
的情况下,但并没有得到选项2的意义。A, B, covariant=True
.
我试着玩了一下 mypy
但似乎搞不清楚。 谁能指出这是什么意思?
I 认为 它的意思是。
A
(或任何子类型的 A
)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)
其实并不正确,要知道价值的局限性 A
和 B
其实并不是共变的。
使用 covariant=True
语法只有在它们相关的时候才有帮助。
协方差和反方差是涉及到对象取向和属相之间的交集的术语。
这就是这个概念要回答的问题。
Base
和Derived
. List<T>
.List<Derived>
哪儿都能用 List<Base>
可以吗?List<Base>
随处可见 List<Derived>
可以吗?如果(3)的答案是肯定的,那就叫协方差,我们就说声明吧 List
视为 covariance=True
. 如果(4)的答案为真,就叫'反变性'。如果都不为真,就是不变性。
界限也来自于OO和泛型的交集。当我们定义了一个泛型MyType--是否意味着'T'可以是任何类型?或者,我可以对T可能是什么施加一些限制吗?界限允许我声明T的上界是,例如,类的 Derived
. 在这种情况下: Base
不能与'MyType'一起使用--但是 Derived
及其所有子类都可以。
协方差和反方差的定义可以在下面找到。PEP-484的这一部分.