告诉 mypy 我肯定知道返回参数的类型

问题描述

以下代码产生了一个 - 可以理解但错误的 - 来自 mypy 的错误

from typing import List,Union,Any

class classA():
    def __init__(self,name: str) -> None:
        self.__name = name

    def __eq__(self,other: Any) -> bool:
        if (type(self) == type(other)):
            return (self.name == other.name)
        return False

    @property
    def name(self) -> str:
        return self.__name


class classB():
    def __init__(self,id: int) -> None:
        self.__id = id

    def __eq__(self,other: Any) -> bool:
        if (type(self) == type(other)):
            return (self.id == other.id)
        return False

    @property
    def id(self) -> int:
        return self.__id


class classC():
    def __init__(self) -> None:
        self.__elements: List[Union[classA,classB]] = list()

    def add(self,elem: Union[classA,classB]) -> None:
        if (elem not in self.__elements):
            self.__elements.append(elem)

    def get_a(self,name_of_a: str) -> classA:
        tmp_a = classA(name_of_a)
        if (tmp_a in self.__elements):
            return self.__elements[self.__elements.index(tmp_a)]
        raise Exception(f'{name_of_a} not found')

    def get_b(self,id_of_b: int) -> classB:
        tmp_b = classB(id_of_b)
        if (tmp_b in self.__elements):
            return self.__elements[self.__elements.index(tmp_b)]
        raise Exception(f'{id_of_b} not found')

调用“mypy --show-error-codes classes.py”显示以下输出
classes.py:43:错误:不兼容的返回值类型(得到“Union[classA,classB]”,预期为“classA”)[返回值]
classes.py:49:错误:不兼容的返回值类型(得到“Union[classA,classB]”,预期为“classB”)[返回值]
在 1 个文件中发现 2 个错误(检查了 1 个源文件

如何告诉 mypy 函数 get_a 只会返回 classA?

解决方法

您可以使用 assert 告诉 mypy:

    def get_a(self,name_of_a: str) -> classA:
        tmp_a = classA(name_of_a)
        if (tmp_a in self.__elements):
            result = self.__elements[self.__elements.index(tmp_a)]
            assert isinstance(result,classA)
            return result
        raise Exception(f'{name_of_a} not found')