【发布时间】:2021-02-12 03:12:51
【问题描述】:
当尝试使用类型的 TypeVar 来启用具有返回类型的泛型时,我遇到了一个 mypy 错误,即在比较字典的类型和预期的返回类型时,bound 参数没有被考虑在内一个函数。
以下是我面临的情况的示例:
from typing import Dict, List, Type, TypeVar
class Bird:
def call(self):
print(self.sound)
class Chicken(Bird):
def __init__(self):
self.sound = "bok bok"
class Owl(Bird):
def __init__(self):
self.sound = "hoot hoot"
T = TypeVar("T", bound=Bird)
class Instantiator:
def __init__(self, birds: List[Type[Bird]]):
self._bird_map: Dict[Type[Bird], Bird] = {}
for bird in birds:
self._bird_map[bird] = bird()
def get_bird(self, bird_type: Type[T]) -> T:
return self._bird_map[bird_type]
运行 mypy 验证器将显示:temp.py:29: error: Incompatible return value type (got "Bird", expected "T")
Instantiator 用作一种“跟踪器”,用于实例化每种鸟类中的一种。当尝试基于类类型检索实例化对象时,这就是为什么需要使用泛型,否则以后键入的字段将抱怨使用 Bird 类而不是 Chicken 或 Owl 之一。
我在这里错误地使用了TypeVar 吗?有没有不同的方法来处理结构?这是 mypy 的疏忽吗?
【问题讨论】:
-
FWIW,
i = Instantiator([Bird, Owl, Chicken]); b = i.get_bird(Owl); b.call()在 Pycharm 中没有导致错误,并且它正确地将b识别为Owl。 -
您的
get_bird也与the docs 中的make_new_user相当接近。 -
是的,谢谢@Carcigenicate,一切仍然正常,所有外部都可以正确输入。我看到错误只是字典类型与
get_bird函数的返回类型。如果使用 mypy 检查,我认为 PyCharm 仍会提示该错误? -
请注意,
list和dict由于可变性而不变。Dict[..., Bird]包含仅Birds 不包含子类。