为何子类用@property重写父类同类型属性会被mypy判定不兼容?
子类用@property重写父类属性为何被mypy拦截?
先看代码示例:
class Foo: bar: str class Bat(Foo): @property def bar(self) -> str: ...
使用mypy检查时会抛出错误:
error: Signature of "bar" incompatible with supertype "Foo" [override]
从读属性的角度看,Foo和Bat实例的bar用法一致,但mypy还是拒绝了这段代码,它要防范的是父类属性可修改、子类属性只读导致的运行时行为不一致问题:
- 父类Foo的
bar是普通实例属性,调用者可以直接执行赋值操作,比如foo.bar = "updated"; - 子类Bat用
@property定义的bar默认是只读属性(没有配套setter的话),如果把Bat实例当成Foo类型来使用,尝试执行bat.bar = "updated"就会触发运行时错误。
mypy的核心目的是提前发现静态类型兼容但实际运行时行为冲突的问题,这也符合里氏替换原则——子类实例必须能无缝替换父类实例,而这段代码里子类破坏了父类属性的可赋值性,违背了这个原则。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

