简体   繁体   中英

Python: type-hinting a classmethod that returns an instance of the class, for a class that is inherited

Consider the following:

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

I want to type-hint the bobo class method, so that mypy can know that in the case of B 's bobo method, it's not just an instance of A that's returned, but actually an instance of B . I'm really unclear on how to do that, or if it's even possible. I thought that something like Type[cls] might do the trick, but I'm not sure if that even makes syntactic sense to mypy.

For an example of how to apply Brian's answer:

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
  • with 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

If your version of Python doesn't have Self yet, you can use the typing-extensions package, which serves as backport for some typing features:

- from typing import Self
+ from typing_extensions import Self

You will have to use a TypeVar , thankfully, in Python 3.11 the typing.Self type is coming out. This PEP describes it in detail. It also specifies how to use the TypeVar until then.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM