Mypy:有什么方法可以实现“SelfType”TypeVar?

Mat*_*GdV 3 python types python-3.x mypy

所以这是一个相当小的问题,但我想知道是否有更熟悉打字模块的人可能知道是否有办法做到这一点。

我希望能够定义一个类型变量,该变量始终等同于它在内部使用的类的实例(如果由子类使用,则等同于该子类类型的实例)。

我目前正在做的是确保 mypy 了解返回值等同于它被调用的类是注释“self”和“cls”参数,如下所示:

from typing import TypeVar, Type

T = TypeVar("T")


class Parent:
    @classmethod
    def from_classmethod(cls: Type[T]) -> T:
        return cls()

    def from_method(self: T) -> T:
        return type(self)()


class Child(Parent):
    pass


Child.from_classmethod()  # mypy: Revealed type is Child
Child().from_method()  # mypy: Revealed type is Child
Run Code Online (Sandbox Code Playgroud)

它确实有效,mypy 会将这些正确解释为类 Child,而不是 Parent。

但是,如果没有必要,我不想这样做。我想知道是否有某种方法可以创建一个像这样工作的 TypeVar:

SelfType = ...  # some voodoo magic goes here


class Parent:
    @classmethod
    def from_classmethod(cls) -> SelfType:
        return cls()

    def from_method(self) -> SelfType:
        return type(self)()


class Child(Parent):
    pass


# OtherParent is reusing SelfType without having to redefine it
class OtherParent:
    @classmethod
    def from_classmethod(cls) -> SelfType:
        return cls()

    def from_method(self) -> SelfType:
        return type(self)()


class OtherChild(OtherParent):
    pass


Child.from_classmethod()  # mypy: Revealed type is Child
Parent.from_classmethod()  # mypy: Revealed type is Parent
OtherChild.from_classmethod()  # mypy: Revealed type is OtherChild
OtherParent.from_classmethod()  # mypy: Revealed type is OtherParent
Run Code Online (Sandbox Code Playgroud)

主要的一点是,我只需要定义一次这个 TypeVar,然后就可以将它应用到我想要的任何类,并让 mypy 从上下文推断该类型与调用它的类相同(即使该方法被继承)。

这完全有可能在我们这边完成,还是需要在 mypy 项目中提出功能请求?

Mih*_*rei 6

你必须定义一个类型变量。请参见本次讨论的话题。

  T = TypeVar('T', bound='Copyable')
  class Copyable:
      def copy(self: T) -> T:
          # return a copy of self
Run Code Online (Sandbox Code Playgroud)