本文介绍了MyPy不允许约束的TypeVar是协变的吗?使用受约束但协变的键值类型定义通用字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试定义一个自定义通用dict,其键的类型为 T_key ,而值的类型为 T_val

我还想对 T_key T_val 施加约束,这样 T_key 只能是 A B 或其子类类型。

I'm trying to define a custom generic dict, whose keys are of type T_key and values are of type T_val.
I also want to put constraints on T_key and T_val, such that T_key can only be of type A or B or their subclass.

我该怎么做?

from typing import TypeVar, Generic

class A: ...
class B: ...

class Asub(A): ...
class Bsub(B): ...

T_key = TypeVar('T_key', A, B, covariant=True)
T_val = TypeVar('T_val', A, B, covariant=True)


class MyDict(Generic[T_key, T_val]): ...


w: MyDict[   A,    B]
x: MyDict[   A, Bsub]
y: MyDict[Asub,    B]
z: MyDict[Asub, Bsub]

当我尝试对此进行检查时,mypy在 x y z 。只有 w 的注释可以按预期工作。

When I try to check this, mypy gives errors on annotations of x, y and z. Only the annotation for w works as expected.

generic.py:17: error: Value of type variable "T_val" of "MyDict" cannot be "Bsub"
generic.py:18: error: Value of type variable "T_key" of "MyDict" cannot be "Asub"
generic.py:19: error: Value of type variable "T_key" of "MyDict" cannot be "Asub"
generic.py:19: error: Value of type variable "T_val" of "MyDict" cannot be "Bsub"

我不明白为什么 Asub covariant = True ,$ c>也不是 T_key 的有效类型。

I don't understand why Asub is not a valid type for T_key even with covariant=True specified.

我在这里想念什么?


推荐答案

这不是协方差的意思。使用协变量类型变量 T 和通用类 Foo [T] Foo的实例[Subclass] 也被视为 Foo [Superclass] 的实例。协方差对 T 可以替代的类型没有影响。

That's not what covariance means. With a covariant type variable T and a generic class Foo[T], instances of Foo[Subclass] are also considered instances of Foo[Superclass]. Covariance has no effect on what types may be substituted for T.

如果您的 B 定义为

class B(A): ...

而不是

class B: ...

,然后输入 MyDict [B,B]类型的值] 由于协方差,被静态类型检查器视为类型 MyDict [A,A] 的有效值。您仍然无法创建类型 MyDict [ASub,BSub] 的值,因为类型变量的唯一有效值是 A B

, then a value of type MyDict[B, B] would be considered a valid value of type MyDict[A, A] by static type checkers due to covariance. You would still not be able to create a value of type MyDict[ASub, BSub], because the only valid values of your type variables are A and B.

您要查找的概念是 bounded 类型变量,使用 bound 关键字参数,而不是受约束的类型变量。看起来您可以指定一个联合作为边界,这让我感到很惊讶,因此将类型变量声明为

The concept you're looking for is bounded type variables, using the bound keyword argument, not constrained type variables. It looks like you can specify a union as the bound, which comes as quite a surprise to me, so declaring the type variables as

T_key = TypeVar('T_key', bound=Union[A, B])
T_val = TypeVar('T_val', bound=Union[A, B])

应该可以。

这篇关于MyPy不允许约束的TypeVar是协变的吗?使用受约束但协变的键值类型定义通用字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 12:09