在下面的代码示例中,我们有一个包含抽象基类实例及其子类型实例的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中的linter警告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中的linter警告,但在mypy中仍会引发错误。你知道吗
从mypy docs我知道“大多数可变的泛型集合是不变的”。因此,我假设dict
是“不变的”?你知道吗
这是否意味着在mypy中不可能有一个包含不同子类实例的dict?如果是这样的话,这个代码是否可以被修改以通过mypy?你知道吗
由于密钥在运行之前是未知的,我假设TypedDict
不是一个选项?你知道吗
您可以使用
cast
告诉mypy
,是的,您承诺d['sub']
将是Sub
(而不仅仅是Base
的未指定子类)的实例,它将具有y
属性。你知道吗从值访问一个字段,当它的类型可以是没有该字段的类型时(在您的例子中是
Base
),从mypy
的角度来看这是一个错误(从我的角度来看也是如此)。你知道吗您应该重新考虑类和继承层次结构,或者添加
isinstance
检查,如而且
mypy
会告诉你相关问题 更多 >
编程相关推荐