如何在没有键入提示错误的情况下指定具有子类的实例?

How to specify an instance with a subclass without typing hint errors?

我正在使用实例 __class__ 属性来指定从超级 class 创建的实例。但是 MyPy 用 Incompatible return value type.

拒绝了它

是否有最 pythonic 的选项可以在不忽略它的情况下做到这一点?

这是我的示例代码:

class A:
    def __init__(self, a: int = None):
        self.a = a or 1


class B(A):
    def b(self) -> int:
        return 5 + self.a

    @classmethod
    def specify(cls, a_instance: A) -> 'B':
        a_instance.__class__ = cls
        return a_instance  # type: ignore


if __name__ == "__main__":
    s = A(6)
    s = B.specify(s)
    print(s.b())

如果您不忽略输入的错误:

 % mypy scratch_7.py
scratch_7.py:13: error: Incompatible return value type (got "A", expected "B")
Found 1 error in 1 file (checked 1 source file)

mypysupports dynamically type casting配合使用typing.cast.

from typing import cast

class B(A):
    def b(self) -> int:
        return 5 + self.a

    @classmethod
    def specify(cls, a_instance: A) -> 'B':
        a_instance.__class__ = cls
        a_instance = cast('B', a_instance)
        return a_instance

# Success: no issues found in 1 source file

typing.cast 不会更改值,它只会向类型检查器 (mypy) 发出类型已更改的信号。