我想与 mypy 一起使用
property setter
属性 getter 和 setter 的类型不同:
from typing import List, Iterable
class Foo:
@property
def x(self) -> List[int]:
...
@x.setter
def x(self, new_x: Iterable[int]):
...
foo = Foo()
foo.x = (1, 2, 3) # error: Incompatible types in assignment (expression has type "Tuple[int, int, int]", variable has type "List[int]")
如何处理此错误?
在将
tuple
分配给预期
List[int]
的属性时收到 Mypy 错误,即使 setter 使用
Iterable[int]
也是如此,因为它比
List[int]
更通用。问题是 Mypy 不会自动将
tuple
转换为
List[int]
。
可以通过以下几种方法解决此错误:
- 在设置器中明确转换类型:
from typing import List, Iterable
class Foo:
@property
def x(self) -> List[int]:
...
@x.setter
def x(self, new_x: Iterable[int]):
self._x = list(new_x) # 将 new_x 转换为 List[int]
foo = Foo()
foo.x = (1, 2, 3) # 现在可以了
此解决方案将传入的
Iterable[int]
转换为
List[int]
,使其与属性的预期类型兼容。
- 使属性类型更通用:
from typing import Iterable
class Foo:
@property
def x(self) -> Iterable[int]:
...
@x.setter
def x(self, new_x: Iterable[int]):
self._x = new_x
foo = Foo()
foo.x = (1, 2, 3) # 现在可以了
在此解决方案中,将属性类型更改为
Iterable[int]
,使其与 setter 中使用的类型相匹配。这允许分配任何类型的可迭代对象,包括元组。
- 在分配时显式转换类型:
from typing import List, Iterable
class Foo:
@property
def x(self) -> List[int]:
...
@x.setter
def x(self, new_x: Iterable[int]):
...
foo = Foo()
foo.x = list((1, 2, 3)) # 将元组转换为列表
此解决方案将分配给属性的值显式转换为
List[int]
。
最佳方法取决于的具体需求和代码库的整体设计。如果需要该属性始终是列表,则第一个解决方案是最佳选择。如果可以使用更通用的可迭代对象类型,则第二个解决方案是更好的选择。第三个解决方案是最不干扰的,但它确实需要在每次分配值时进行显式转换。
标签:python,python-typing,mypy From: 59964767