NamedTuple的子类提供不兼容的返回类型/参数类型

时间:2020-02-20 16:22:44

标签: python mypy

请考虑以下代码段:

class A_TUPLE(NamedTuple):
    ...

class Animal:
    def get(self) -> Sequence[NamedTuple]:
        ...

    def get_one(self, x: Sequence[NamedTuple]) -> None:
        ...

class Dog(Animal):
    def get(self) -> Sequence[A_TUPLE]:  # error: Return type "Sequence[A_TUPLE]" of "get" incompatible with return type "Sequence[NamedTuple]" in supertype "Animal"
        ...
    def get_one(self, x: Sequence[A_TUPLE]) -> None:  # error: Argument 1 of "get_one" is incompatible with supertype "Animal"; supertype defines the argument type as "Sequence[NamedTuple]"
        ...

在上述代码段上运行mypy会产生错误,如注释中所示。

根据mypy - invariance,这应该是可能的。

1 个答案:

答案 0 :(得分:2)

Sequence[NamedTuple]Sequence[A_TUPLE]仅在事先知道NamedTuple的名称/类型时才兼容。否则,仅使用NamedTuple声明就无法验证派生类的返回类型与基类兼容还是安全。

例如这将起作用:

class A_TUPLE(NamedTuple):
    a: str
    b: int

class Animal:
    def get(self) -> Sequence[Tuple[str, int]]:
        ...

class Dog(Animal):
    def get(self) -> Sequence[A_TUPLE]:  # okay!
        ...

第二个功能def get_one(self, x: Sequence[A_TUPLE])有一个不同的问题。 基类版本表示get_one()可以采用任何元组,而派生版本则需要特定的类型A_TUPLE。但是,如果您有狗,可以将其视为动物。因此,Dog必须接受Animal接受的所有内容,在此情况并非如此。

相关问题