mypy:包含不同子类实例的Dict

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

在下面的代码示例中,我们有一个dict,其中包含一个抽象基类的实例及其子类型的实例。

from typing import Dict, Union


class Base:
    def __init__(self):
        self.x = 0


class Sub(Base):
    def __init__(self):
        super().__init__()
        self.y = 1


d: Dict[str, Base] = {
    'base': Base(),
    'sub': Sub()
}

print(d['sub'].y)

访问子类型的实例变量会导致皮卡姆(Pycharm)出现短绒警告Unresolved attribute reference 'y' for class 'Base'

与mypy一起检查此示例将引发错误:

error: Item "Base" of "Union[Base, Sub]" has no attribute "y"

将代码更改为

d: Dict[str, Union[Base, Sub]] = {
    'base': Base(),
    'sub': Sub()
}

修复了Pycharm中的短毛绒警告,但在mypy中仍然出现该错误。

mypy docs我知道“大多数可变的通用集合是不变的”。因此,我认为dict是“不变的”?

这是否意味着无法在mypy中使用不同子类的实例进行字典?如果是这样,可以以某种方式更改此代码,使其通过mypy吗?

由于在运行时之前不知道键,所以我认为TypedDict不是一个选项?

python pycharm type-hinting typing mypy
1个回答
0
投票

[当值的类型可以是没有该字段的类型时访问值的字段(在您的情况下为Base -从mypy的角度来看(也是我的))错误。

您应该重新考虑您的类和继承层次结构,或者添加isinstance检查类似

... # same as before
value = d['sub']
if isinstance(value, Sub):
    print(value.y)

[mypy会说类似的东西

Success: no issues found in 1 source file
© www.soinside.com 2019 - 2024. All rights reserved.