抽象基类的Python子类显示类型错误

问题描述 投票:0回答:1

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类型)而不重写函数本身?

python typing pylance
1个回答
0
投票

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 也写下他的评论作为答案,我想投票并接受他的答案。

© www.soinside.com 2019 - 2024. All rights reserved.