在下面的代码示例中,我们有一个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
不是一个选项?
[当值的类型可以是没有该字段的类型时访问值的字段(在您的情况下为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