为什么变量的类型提示不作为函数参数的类型提示处理?

Why are type hints for variables not handled as type hints for function parameters?

在 Python 中使用类型提示编写函数时:

def foo(token: Token=None):
  pass

它转换为这种类型提示:Optional[Token]。对于可选的,None 值也被接受。


为 class 字段编写相同类型的提示时,它的行为不同:

class bar:
  foo: Token = None

在此处键入提示检查器,例如 PyCharm 报告中的集成提示检查器:

Expected type 'Token', got None instead.

我的问题是:

我用的是PyCharm2019.3.

Why is in the parameter case the hint and None implicitly combined to Optional[...]

这就是 PyCharm 的静态类型检查器在参数的默认值设置为 None 时推断参数类型的方式。它推断类型成为您声明的 Optional[type] 。此推理规则以不同方式应用于签名之外的变量声明。

Why do fields behave differently, while having the same syntax?

根据我们从以下来源了解到的内容,这是一个语法细节选择,旨在使签名更简洁,尽管引入了隐式规则。

PyCharm 的静态类型检查器的实现方式与历史 PEP 484 更改保持一致。当前修订状态:

Union types - PEP 484

A past version of this PEP allowed type checkers to assume an optional type when the default value is None, as in this code:

def handle_employee(e: Employee = None): ...

This would have been treated as equivalent to:

def handle_employee(e: Optional[Employee] = None) -> None: ...

This is no longer the recommended behavior. Type checkers should move towards requiring the optional type to be made explicit.

查看修订历史"PEP 484: Do not require type checkers to treat a None default special…" the reasons are given in Pull request #689 linking back to typing issue #275

我更改了您的代码,因为 Token 未定义,改为:

def foo(token: int = None) -> None:
  pass

class bar:
  foo: int = None

使用带有 default configurations 的 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 inspection 具有为此的可配置选项。