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

标签 python python-3.x pycharm typechecking python-typing

当用 Python 编写带有如下类型提示的函数时:

def foo(token: Token=None):
  pass

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


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

class bar:
  foo: Token = None

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

Expected type 'Token', got None instead.

我的问题是:

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

我使用 PyCharm 2019.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…"原因在 Pull request #689 中给出链接回typing issue #275 .

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

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

class bar:
  foo: int = None

使用 mypy 静态类型检查器 default configurations警告按预期发出:

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为此有一个可配置的选项。

关于python - 为什么变量的类型提示不作为函数参数的类型提示处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59777841/

相关文章:

python - 在Python中,如何分割字符串并保留分隔符?

python - PYQT5:窗口没有获得焦点

pycharm - 为什么我不能从 PyCharm 复制粘贴到 Maya 脚本编辑器中?

python - super() 和显式 super(Cl,self) 之间有什么区别(带有 __slots__ 和 attrs)

javascript - Django:如何在过滤后刷新表格而不刷新整个页面?

python - PyCharm 中的 "Unresolved attribute reference"

python - 检查程序是否在 Debug 模式下运行

python - 将 16 位值拆分为 12+4 python 结构

python - 匹配字符串末尾的模式?

python - 二叉树叶子值的总和