简体   繁体   English

Python 为子类的实例键入签名?

[英]Python typing signature for instance of subclass?

Consider:考虑:

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()

Running mypy on this we 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)

Additionally, I have checked to see if old-style recursive annotations work.此外,我检查了旧式递归注释是否有效。 That is:那是:

# from __future__ import annotations

class A:
    @classmethod
    def get(cls) -> "A":
# ...

...to no avail. ……无济于事。

Of course one could do:当然可以这样做:

from typing import cast

def func() -> B: # Line 12
    return cast(B, B.get())

Every time this case pops up.每次出现这种情况。 But I would like to avoid doing that.但我想避免这样做。

How should one go about typing this?一个go应该怎么打字?

The cls and self parameters are usually inferred by mpyp to avoid a lot of redundant code, but when required they can be specified explicitly by annotations. clsself参数通常由mpyp推断,以避免大量冗余代码,但在需要时可以通过注释显式指定它们。

In this case the explicit type for the class method would look like the following:在这种情况下,class 方法的显式类型如下所示:

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

So what we really need here is a way to make Type[A] a generic parameter, such that when the class method is called from a child class, you can reference the child class instead.所以我们这里真正需要的是一种使Type[A]成为泛型参数的方法,这样当从子 class 调用 class 方法时,您可以改为引用子 class。 Luckily, we have TypeVar values for this.幸运的是,我们为此提供了TypeVar值。

Working this into your existing example we will get the following:将此应用到您现有的示例中,我们将获得以下信息:

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()

Now mypy should be your friend again!现在mypy应该再次成为你的朋友!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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