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

问题描述 投票:0回答:1

在 Python 中编写具有如下类型提示的函数时:

def foo(token: Token=None):
  pass

它翻译成这种类型提示:

Optional[Token]
。对于可选,也接受
None
值。


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

class bar:
  foo: Token = None

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

预期类型“Token”,却得到 None。

我的问题是:

  • 为什么在参数大小写中提示和
    None
    隐式组合成
    Optional[...]
  • 为什么字段的行为不同,但具有相同的语法?

我使用PyCharm 2019.3。

python pycharm python-typing
1个回答
2
投票

为什么在参数大小写中hint和None隐式组合成Optional[...]

这就是 PyCharm 的静态类型检查器在默认值设置为

None
时推断参数类型的方式。它推断出您所声明的类型将成为
Optional[type]
。对于签名之外的变量声明,此推理规则的应用有所不同。

为什么字段的行为不同,但具有相同的语法?

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

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

工会类型 - 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 检查 有可配置的选项。

© www.soinside.com 2019 - 2024. All rights reserved.