如何避免因 __init__ 中设置的默认值而出现类型检查器警告?

How to avoid type checker warnings due to default values set in __init__?

在我的应用程序中有很多 classes 的情况基本上是这样的:

class A:

    def __init__(self) -> None:
        self.subject = None

    def set_subject(self, subject: SpecificClass) -> None:
        self.subject = subject

    def do_something_with_subject(self) -> None:
        self.subject.do_stuff()

do_something_with_subject()总是在set_subject()之后调用,这是程序的不变量,但我必须先创建class A,然后我才知道要将主题设置为什么,所以现在我在 __init__() 中设置默认值。在 subject 的情况下,唯一的逻辑默认值是 None.

现在问题来了:我的静态类型检查器 (pyright) 抱怨 self.subject.do_stuff()。因为它在 __init__() 中看到 subject 可以是 None,它告诉我 do_stuff() 不是 None 的成员。一切都非常合理,除了这不是我希望看到的警告,考虑到我的程序是如何运行的。我也:

在这种情况下,有什么方法可以让我既吃蛋糕又吃蛋糕吗?将 subject 置于类型检查审查之下,以某种方式在 __init__() 中声明它,不要让类型检查器认为它可以是 None?

安抚类型检查器的一种轻松方法是将其设为 do_something_with_subject 的第一行。

assert self.subject is not None

这肯定会安抚 mypy,它将此行中的所有内容拼凑在一起。

这可以通过使用 cast 来实现。 self.subject = cast(SpecificClass, None) 将 return 值 (None) 不变,但会向类型检查器发出信号,表明它具有特定类型 (SpecificClass)。