pylance 在定义变量类型时给出类型错误。下面是一个小示例,显示了代码的结构并给出了错误:
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Generator, Any
@dataclass
class Base(ABC):
data: list[str | int]
def __iter__(self) -> Generator[str | int, Any, None]:
for xin self.data:
yield x
def __getitem__(self, key) -> str | int:
return self.data[key]
def __len__(self) -> int:
return len(self.data)
@abstractmethod
def some_general_function(self) -> None:
pass
class Test1(Base):
data: list[str]
def some_general_function(self) -> None:
print("General function from list with strings")
if __name__ == '__main__':
test = Test1(['a', 'b', 'abc'])
for ele in test:
print(ele.capitalize)
错误在最后一行,错误表明函数
.capitalize
不适用于类型int
。
在类 (
Test1
) 的实现中,定义列表数据由类型为 str
的元素组成。
此外,当在
__post_init__
类中的 Test1
方法中进行测试时,错误仍然存在。
class Test1(Base):
data: list[str]
def __post_init__(self):
if not any(map(lambda x: isinstance(x, str), self.data)):
raise TypeError("data should be a
唯一的解决方案是重写基类的
__iter__
,因为那里的类型提示表明生成器可以是 str
和 int
。
是否可以只重写函数的返回类型(或yield类型)而不重写函数本身?
STerliakov 的评论中给出了答案。使用库中的
TypeVar
和 Generic
typing
可以调整代码,使其返回想要的内容。
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Generator, Any, TypeVar, Generic
_T = TypeVar("_T")
@dataclass
class Base(ABC, Generic[_T]):
data: list[_T]
def __iter__(self) -> Generator[_T, Any, None]:
for x in self.data:
yield x
def __getitem__(self, key: int) -> _T:
return self.data[key]
def __len__(self) -> int:
return len(self.data)
@abstractmethod
def some_general_function(self) -> None:
pass
class Test1(Base[str]):
def some_general_function(self) -> None:
print("General function from list with strings")
if __name__ == '__main__':
test = Test1(['a', 'b', 'abc'])
for ele in test:
print(ele.capitalize())
关于
TypeVar
的解释可以在这里找到:https://dev.to/decorator_factory/typevars-explained-hmo
Generic
参数解释如下:https://mypy.readthedocs.io/en/stable/generics.html
编辑 如果 STerliakov 也写下他的评论作为答案,我想投票并接受他的答案。