对于简单的情况,实际上可以不用在构造函数中执行任何操作:如果执行以下操作,mypy和Pycharm将继续正确推断字段的类型:
class SomeClass:
def called_during_runtime(self) -> None:
self._unassigned_val = 1.0
如果您的函数以足够复杂的方式为该字段赋值,则类型检查器可能会阻塞,不知道该做什么。在这种情况下,您可以使用
Variable annotations
如果您使用的是Python3.6或更高版本:
class SomeClass:
_unassigned_val: float
def called_during_runtime(self) -> None:
self._unassigned_val = 1.0
这完全等同于运行时的第一种方法。
如果需要支持较旧版本的Python,则可以使用另一种技术创建一个“假”sentinel值,该值被赋予一种
Any
,全动态类型:
from typing import Any
BOGUS = object() # type: Any
class SomeClass:
def __init__(self) -> None:
self._unassigned_val = BOGUS # type: float
def called_during_runtime(self) -> None:
self._unassigned_val = 1.0
如果您改变主意并决定偏向类型检查器,请更积极地处理其警告,您可以始终声明您的值可以是
任何一个
浮动或无:
from typing import Optional
class SomeClass:
def __init__(self) -> None:
self._unassigned_val = None # type: Optional[float]
def called_during_runtime(self) -> None:
self._unassigned_val = 1.0
def get_with_default(self, default: float) -> float:
if self._unassigned_val is None:
return default
else:
return self._unassigned_val
注意,然后可以使用
self._unassigned_val is not None
,
self._unassigned_val is None
,或
isinstance(self._unassigned_val, float)
在if语句中检查,并断言让类型检查器有条件地缩小字段的类型。
最后一种方法是我个人所做的:我是类型检查程序的粉丝,并且设置我的工具来非常积极地检测潜在的问题。
关于省略号的最后一个注意事项:使用省略号作为占位符仅适用于存根,并且在处理诸如
Protocols
abstract classes
--基本上,如果您在运行时从未实际使用字段/方法参数/任何东西的值。