如何修复classproperty与继承重写非属性成员间的静态类型错误
可以通过为classproperty添加符合类型检查器规则的泛型注解解决该问题,原有运行时逻辑完全不需要修改,仅补充类型标注即可让mypy正确识别类属性的实际类型。
修改后的完整实现
from typing import Any, TypeVar, Generic, overload, Type T = TypeVar('T') class classproperty(Generic[T], property): @overload def __get__(self, instance: None, owner: Type[Any]) -> T: ... @overload def __get__(self, instance: Any, owner: Type[Any]) -> T: ... def __get__(self, cls, owner): return classmethod(self.fget).__get__(None, owner)()
原理说明
- 引入泛型参数
T绑定类属性的返回值类型,和装饰方法标注的返回类型自动匹配 - 为描述符协议的
__get__方法添加重载注解,明确告诉mypy:无论从类访问还是实例访问该属性,最终返回值都是T类型,而非可调用对象类型 - 运行时逻辑和原有实现完全一致,不影响无实例类场景的使用效果
验证示例
使用上述实现后,原有代码不会再触发mypy类型错误:
class A: @classproperty def foo(cls) -> str: return 'bar' class B(A): foo = 'not bar' # mypy识别foo为str类型,无类型不匹配报错
内容的提问来源于stack exchange,提问作者AmazingMiki
相关产品推荐
相关产品推荐

