我有一个类需要采取一系列的操作:
class SomeModel:
def __init__(self):
pass
def predict(self, X):
return None
class Model:
def __init__(self):
self.inner_model = None
def _check_trained(self):
# Simplified; real version has more checks.
assert self.inner_model is not None
def train(self, X, y):
self.inner_model = SomeModel()
# More code here
def predict(self, X):
self._check_trained()
return self.inner_model.predict(X)Pylance在self.inner_model.predict上给出了一个类型错误,因为self.inner_model可能是None。但是,以前的检查阻止了这一点。展开列车检查功能将修复这一点,但将无法使用。
是否有一种使用函数验证None属性的方法?或者我需要显式地禁用这一行的类型检查吗?
附加上下文: VSCode 1.65.2 Pylance v2022.3.2基本类型检查模式的Pylance。
编辑:这是我得到的行为的截图。
发布于 2022-03-18 06:42:00
正如@brokenbenchmark所说,类型检查不会跨越函数边界,因此将self.inner_model视为一个Optional[Model]。
一种方法是从self._check_trained()返回内部模型,并键入它的返回类型。
class Model:
def __init__(self):
self.inner_model = None
def _check_trained(self) -> SomeModel:
# Simplified; real version has more checks.
assert self.inner_model is not None
return self.inner_model
def train(self, X, y):
self.inner_model = SomeModel()
# More code here
def predict(self, X):
inner_model = self._check_trained()
return inner_model.predict(X)其他可能的替代办法:
__init__中强制内部模型的赋值,使其不能是Noneinner_model存储为私有变量,并通过执行检查并返回SomeModel的属性公开它class Model:
def __init__(self):
self._inner_model = None
@property
def inner_model(self) -> SomeModel:
assert self._inner_model is not None
return self._inner_model
def _check_trained(self):
# Simplified; real version has more checks.
assert self.inner_model is not None
def train(self, X, y):
self._inner_model = SomeModel()
# More code here
def predict(self, X):
self._check_trained()
return self.inner_model.predict(X)发布于 2022-03-18 06:15:15
它看起来不像Pylance将断言作为函数的后置条件。我找不到这方面的具体来源,但我从其他静态分析工具中看到了这样的行为--自动生成这样的后置条件可能会使分析很快变得棘手。
您可以在调用# type: ignore的行中使用.predict(),但是如果您多次访问同一个变量,最好使用cast(),如下所示:
from typing import cast
def predict(self, X):
self._check_trained()
inner_model = cast(SomeModel, self.inner_model)
return inner_model.predict(X)关于使用Pylance处理可空值的一些进一步讨论可以找到这里。
https://stackoverflow.com/questions/71520182
复制相似问题