问题描述
我有一个代码库,我想使用 mypy 进行验证.在当前的设计中,一个类可能有一个非原始成员,可以在 __init__
之后设置,这是很常见的.
I have a codebase which I would like to validate using mypy. In the current design, it is very common that a class may have a non-primitive member that can be set later after __init__
.
因此,在 __init__
中,成员被初始化为 None
,其类型相应地变为 Optional
.
So, in __init__
the member is initialized to None
and its type becomes Optional
accordingly.
问题是现在MyPy
要求我在每次使用时检查该成员是否为None
.
The problem is that now MyPy
requires me to check that the member is not None
every time it is being used.
作为一个快速解决方案,我可以在所有相关范围内添加 assert self._member is not None # MyPy
,但这似乎是一个非常糟糕的做法.
As a quick solution I can add assert self._member is not None # MyPy
in all the relevant scopes, but it seems like a very bad practice.
另一个想法是添加一个 @property
并在内部进行断言,但这似乎也是一个巨大的开销.
Another idea would be to add a @property
and do the assertion inside, but this also seems like a huge overhead.
是否有更自然/更正确的设计可以克服这个问题?
Is there a more natural/correct design that can overcome this issue?
澄清一下,我的代码是完全类型注释的.
To clarify, my code is fully type annotated.
成员定义为self._member: Optional[MemberType]
.
推荐答案
如果在 __init__
之外分配了一个实例变量,那么该类的一个实例可能处于该变量不在的状态放.老实说,在使用它的功能中应该考虑到这一点.但是如果我们相信或者保证在这个状态下这些函数不会被调用,那么我们可以这样注释这个实例成员:
If an instance variable is assigned outside of __init__
, then an instance of the class may be in a state where the variable is not set. And to be honest, this should be taken into account in the functions using it. But if we believe or ensure that these functions will not be called in this state, then we can annotate this instance member as follows:
class Foo:
var_1: int # variant 1
def __init__(self) -> None:
self.var_2: int # variant 2
这些语句不会创建真正的变量,只有 mypy
这篇关于重构以满足 mypy 要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!