Int*_*rer 17 python oop static-typing covariance mypy
今天我深入研究了 Liskov 的替换原则和协方差/逆变。
我被困在以下之间的区别上:
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 是协变的?定义具有约束但协变的键值类型的通用字典
重新提及bound=Union[A, B]
案例,但没有理解选项#2 的含义,A, B, covariant=True
。
我试过玩弄mypy
,但似乎无法弄清楚。
谁能指出这是什么意思?
我认为这意味着:
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
Run Code Online (Sandbox Code Playgroud)
**编辑 2**
我最终在python/mypy #8806 中询问了这个问题:当 T_co = TypeVar("T_co", A, B, covariant=True) 并传递 A 的子类时,Generic[T_co] 出错
这消除了我的一些误解。事实证明TypeVar("T", A, B, covariant=True)
并不是真的正确,知道值限制A
并且B
实际上不是协变的。
covariant=True
语法的使用只有在它们相关时才有用。
Roy*_*012 15
协方差和逆变是与面向对象和泛型之间的交集相关的术语。
这是这个概念试图回答的问题:
Base
和
Derived
.List<T>
.List<Derived>
可以在任何地方使用List<Base>
?List<Base>
可以在任何地方使用List<Derived>
?如果(3)的答案是肯定的,则称为协方差,我们会说声明List
为具有covariance=True
。如果 (4) 的答案为真,则称为“逆方差”。如果没有一个是真的,它是不变的。
边界也来自 OO 和泛型的交集。当我们定义一个泛型类型 MyType 时 - 这是否意味着 'T' 可以是任何类型?或者,我可以对 T 可能是什么施加一些限制吗?Bounds 允许我声明 T 的上限是,例如, class Derived
。在这种情况下,Base
不能与 'MyType' 一起使用 - 但Derived
它的所有子类都可以。
协方差和逆变的定义可以在PEP-484 的这一节中找到。
归档时间: |
|
查看次数: |
2939 次 |
最近记录: |