如何解决Python property类型不兼容引发的mypy警告?
解决mypy对Python property赋值的类型警告问题
问题原因
mypy根据@property装饰的getter方法返回类型,推断self.start的类型为datetime.datetime,但你在__init__中给它赋值了str类型,导致触发"Incompatible types in assignment"警告。
解决方案一:直接初始化底层变量
绕过property的setter,在__init__中直接处理输入字符串并赋值给底层的_start变量,确保类型完全匹配:
import datetime from typing import ClassVar class TestProperty(object): today: ClassVar[datetime.datetime] = datetime.datetime.today() def __init__(self, start: str): start_h, start_m = [int(val) for val in start.split(":")] self._start: datetime.datetime = TestProperty.today.replace(hour=start_h, minute=start_m) @property def start(self) -> datetime.datetime: return self._start @start.setter def start(self, value: str) -> None: start_h, start_m = [int(val) for val in value.split(":")] self._start: datetime.datetime = TestProperty.today.replace(hour=start_h, minute=start_m) if __name__ == "__main__": tp = TestProperty("12:00") print(tp.start)
解决方案二:用@overload标注property的读写类型
通过typing.overload分别标注getter和setter的类型,明确告知mypy:读取start时返回datetime.datetime,赋值时接受str类型:
import datetime from typing import ClassVar, overload class TestProperty(object): today: ClassVar[datetime.datetime] = datetime.datetime.today() def __init__(self, start: str): self.start = start @overload @property def start(self) -> datetime.datetime: ... @overload @start.setter def start(self, value: str) -> None: ... @property def start(self) -> datetime.datetime: return self._start @start.setter def start(self, value: str) -> None: start_h, start_m = [int(val) for val in value.split(":")] self._start: datetime.datetime = TestProperty.today.replace(hour=start_h, minute=start_m) if __name__ == "__main__": tp = TestProperty("12:00") print(tp.start)
说明
- 方案一简洁直接,避免了类型推断冲突;
- 方案二更贴合property的设计意图,通过静态类型标注让工具准确理解代码逻辑。
内容的提问来源于stack exchange,提问作者user2190356
相关产品推荐
相关产品推荐

