根据python中键描述的类型键入字典的值

时间:2021-02-11 15:03:51

标签: python list dictionary typing mypy

美好的一天,

我在输入 Python 时遇到以下问题:

我想表达一个字典的值是值列表。其中列表中值的类型必须是键本身描述的类型。

用例是我想根据元素的类存储一个元素列表,以便我可以编写一个函数,该函数可以返回基于类的第一个元素。

这是我目前想到的:

# ... imports ...

T = TypeVar("T", bound=SomeBaseClass)
ClassIndexedListDict = Dict[Type[T], List[T]]


class SubClassList:

    def __init__(self, *args: SomeBaseClass) -> None:
        self.__elementsByClass: ClassIndexedListDict = {}
        for elem in args:
            if type(elem) not in self.__elementsByClass:
                self.__elementsByClass[type(elem)] = []
            self.__elementsByClass[type(elem)].append(elem)

    def getFirst(self, cls: Type[T]) -> T:
        return self.__elementsByClass[cls][0]

class Usage:

    def __init__(self) -> None:
        self.__list = SubClassList(SubClassA(), SubClassB())  # SubClassA and SubClassB both extend SomeBaseClass
    
    def foo(self) -> int:
        self.__list.getFirst(SubClassA).methodInSubClassA()  # no linting error
        self.__list.getFirst(SubClassB).methodInSubClassA()  # linting error, as return value of self.__list.getFirst(SubClassB) must be of type SubClassB

但这显然允许字典具有任何价值?

至少有一本这样的字典

self.__elementsByClass = {
    int: ["test"]
}

使用 mypy linting 时似乎不会抛出任何错误。

在此之前,我尝试将字典简单地键入为 Dict[Type[SomeBaseClass], List[SomeBaseClass]],但是 getFirst 函数存在问题,因为返回的类型必须与作为参数给出的类型相匹配,可以是SomeBaseClass 的子类。

是否可以表达此约束,以便 mypy 在 getFirst 函数内部注意到,字典中键 T 处的所有元素都必须是 T 类型,因此返回值也必须是 T 类型?< /p>

0 个答案:

没有答案