当用 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 更改保持一致。当前修订指出:
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/