请考虑以下代码段:
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,这应该是可能的。
答案 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接受的所有内容,在此情况并非如此。