在 Python 中编写具有如下类型提示的函数时:
def foo(token: Token=None):
pass
它翻译成这种类型提示:
Optional[Token]
。对于可选,也接受 None
值。
为类字段编写相同的类型提示时,其行为并不相同:
class bar:
foo: Token = None
在此输入提示检查器,例如 PyCharm 报告中的集成提示检查器:
预期类型“Token”,却得到 None。
我的问题是:
None
隐式组合成Optional[...]
?我使用PyCharm 2019.3。
为什么在参数大小写中hint和None隐式组合成Optional[...]
这就是 PyCharm 的静态类型检查器在默认值设置为
None
时推断参数类型的方式。它推断出您所声明的类型将成为 Optional[type]
。对于签名之外的变量声明,此推理规则的应用有所不同。
为什么字段的行为不同,但具有相同的语法?
根据我们从以下来源了解到的情况,这是一个语法细节选择,旨在使签名更加简洁,尽管引入了隐式规则。
PyCharm 静态类型检查器的实现方式与历史 PEP 484 更改保持一致。当前修订指出:
此 PEP 的过去版本允许类型检查器在默认值为 None 时采用可选类型,如以下代码所示:
def handle_employee(e: Employee = None): ...
这将被视为等同于:
def handle_employee(e: Optional[Employee] = None) -> None: ...
这不再是推荐的行为。类型检查器应该朝着要求明确可选类型的方向发展。
查看修订历史记录 “PEP 484:不需要类型检查器来处理 None 默认特殊…” 原因在 拉取请求 #689 链接回 打字问题 #275。
我更改了您的代码,因为
Token
未定义,为:
def foo(token: int = None) -> None:
pass
class bar:
foo: int = None
使用 mypy 静态类型检查器和默认配置,警告会按预期发出:
error: Incompatible default for argument "token" (default has type "None", argument has type "int")
error: Incompatible types in assignment (expression has type "None", variable has type "int")
我没有找到任何 PyCharm 检查 有可配置的选项。