gpt4 book ai didi

子类实例的 Python 类型签名?

转载 作者:行者123 更新时间:2023-12-04 08:10:57 26 4
gpt4 key购买 nike

考虑:

from __future__ import annotations

class A:
@classmethod
def get(cls) -> A:
return cls()

class B(A):
pass

def func() -> B: # Line 12
return B.get()
运行 mypy 我们得到:
$ mypy test.py
test.py:12: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)
此外,我还检查了旧式递归注释是否有效。那是:
# from __future__ import annotations

class A:
@classmethod
def get(cls) -> "A":
# ...
……无济于事。
当然可以这样做:
from typing import cast

def func() -> B: # Line 12
return cast(B, B.get())
每次出现这种情况。但我想避免这样做。
应该如何打字呢?

最佳答案

clsself参数通常由mpyp推断避免大量冗余代码,但在需要时可以通过注释明确指定。
在这种情况下,类方法的显式类型如下所示:

class A:
@classmethod
def get(cls: Type[A]) -> A:
return cls()
所以我们在这里真正需要的是一种制作 Type[A] 的方法。一个泛型参数,这样当从子类调用类方法时,您可以改为引用子类。幸运的是,我们有 TypeVar为此的值(value)。
将此应用到您现有的示例中,我们将获得以下结果:
from __future__ import annotations

from typing import TypeVar, Type


T = TypeVar('T')


class A:
@classmethod
def get(cls: Type[T]) -> T:
return cls()


class B(A):
pass


def func() -> B:
return B.get()
现在 mypy应该再次成为你的 friend ! 😎

关于子类实例的 Python 类型签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65963177/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com