Python类型注解:继承方法的返回类型

Posted

技术标签:

【中文标题】Python类型注解:继承方法的返回类型【英文标题】:Python type annotations: return type of inherited method 【发布时间】:2020-11-20 11:45:48 【问题描述】:

我创建了一个自定义的类字典类来简化跨大型数据集的合并评估指标。这个类实现了一个__add__方法来总结各种指标。

这是我正在处理的代码的简化版本:

from __future__ import annotations
from typing import TypeVar, Dict


T = TypeVar('T', int, float)


class AddableDict(Dict[str, T]):
    def __add__(self, other: AddableDict[T]) -> AddableDict[T]:
        if not isinstance(other, self.__class__):
            raise ValueError()
        new_dict = self.__class__()
        all_keys = set(list(self.keys()) + list(other.keys()))
        for key in all_keys:
            new_dict[key] = self.get(key, 0) + other.get(key, 0)
        return new_dict


# AddableIntDict = AddableDict[int]
# this would work just fine, however I need to add a few additional methods


class AddableIntDict(AddableDict[int]):
    def some_int_specific_method(self) -> None:
        pass


def main() -> None:
    x = AddableIntDict()
    y = AddableIntDict()
    x['a'] = 1
    y['a'] = 3

    x += y  # breaks mypy

程序的最后一行打破了 mypy (0.782) 并出现以下错误:

error: Incompatible types in assignment (expression has type "AddableDict[int]", variable has type "AddableIntDict")

这个错误对我来说很有意义。

当我将AddableIntDict 定义为AddableDict[int] 的类型别名时,代码运行良好,正如我在评论中所指出的那样,但是因为我需要根据字典值的类型添加其他方法,如@987654326 所示@,我不能简单地使用类型别名。

谁能指出我正确的方向,如何注释父类的__add__ 方法,以便它返回调用类的类型?

(我使用的是 Python 3.8.3)

【问题讨论】:

顺便说一句,all_keys = set(list(self.keys()) + list(other.keys())) 可以只是 all_keys = self.keys() | other.keys(),因为 dict 键视图对象已经实现了类似集合的操作 另外,顺便说一句,看起来这只是重新发明collections.Counter 感谢@juanpa.arrivillaga 的| 提示。我熟悉Counters。我正在实现的类引入了更复杂的逻辑,尽管它可能可以重写为使用Counters。 【参考方案1】:

可以使用类型变量来引用“self的类型”。这将解析为调用方法的基类或子类的适当类型:

from typing import TypeVar, Dict


T = TypeVar('T', int, float)
AD = TypeVar('AD', bound='AddableDict')


class AddableDict(Dict[str, T]):
    def __add__(self: AD, other: AD) -> AD: ...


class AddableIntDict(AddableDict[int]):
    def some_int_specific_method(self) -> None: ...

x = AddableIntDict(a=1)
y = AddableIntDict(a=3)
x += y  # works for mypy and others

【讨论】:

注意:mypy 错误认为AddableDict 是带有--strict 标志的“缺少泛型类型的类型参数”。但是,您似乎可以放心地忽略这些错误。

以上是关于Python类型注解:继承方法的返回类型的主要内容,如果未能解决你的问题,请参考以下文章

注解:@interface 自定义注解的语法

注解:@interface 自定义注解的语法

Python方法和返回值(Union)联合类型注解

8.注解:@interface 自定义注解的语法

java 类方法的注解的继承问题

Python void 返回类型注解