Python:对于继承的类,类型提示返回类实例的类方法

Tri*_*sne 11 python typing mypy

考虑以下:

from __future__ import annotations

class A:

    def __init__(self):
        print("A")
        self.hello = "hello"

    # how do I type this so that the return type is A for A.bobo()
    # and B for B.bobo()?
    @classmethod
    def bobo(cls) -> UnknownType:
        return cls()


class B(A):

    def __init__(self):
        print("B")
        super().__init__()
        self.world = "world"


instance_of_B = B.bobo()  # prints "B", then "A", and returns an instance of B
Run Code Online (Sandbox Code Playgroud)

我想对类方法进行类型提示,以便 mypy 可以知道,在s方法bobo的情况下,它不仅仅是返回的实例,而且实际上是 的实例。我真的不清楚如何做到这一点,或者是否可能。我认为类似的东西可能会起作用,但我不确定这对 mypy 是否具有语法意义。BboboABType[cls]

dec*_*ory 22

有关如何应用布莱恩的答案的示例:

from typing import TypeVar


AnyA = TypeVar("AnyA", bound="A")


class A:

    def __init__(self):
        print("A")
        self.hello = "hello"

    @classmethod
    def bobo(cls: type[AnyA]) -> AnyA:
        return cls()

class B(A):

    def __init__(self):
        print("B")
        super().__init__()
        self.world = "world"

reveal_type(B.bobo())  # B
Run Code Online (Sandbox Code Playgroud)
  • Self
from typing import Self

class A:

    def __init__(self):
        print("A")
        self.hello = "hello"

    @classmethod
    def bobo(cls) -> Self:
        return cls()

class B(A):

    def __init__(self):
        print("B")
        super().__init__()
        self.world = "world"

reveal_type(B.bobo())  # B
Run Code Online (Sandbox Code Playgroud)

如果您的 Python 版本还没有Self,您可以使用Typing-extensions包,它充当某些类型功能的向后移植:

- from typing import Self
+ from typing_extensions import Self
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 6

值得庆幸的是,你必须使用 a TypeVar,在 Python 3.11 中,该typing.Self类型已经出现。本 PEP对此进行了详细描述。它还指定如何使用TypeVar截至那时。

  • 通过解释“如何”使用“TypeVar”,这个答案将得到显着改善。现在,这只是对文档的暗示。 (5认同)