在Python 3.6中,语言中引入了新的 变量注释
但是,当类型不存在时,可能会发生两种不同的情况:
>>> def test():
... a: something = 0
...
>>> test()
>>>
>>> a: something = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'something' is not defined
为什么要处理不存在的类型行为不同?难道它不会潜在地导致人们忽略函数中未定义的类型吗?
注释
尝试使用Python 3.6 RC1和RC2 - 相同的行为。
PyCharm突出
something
在两者中都作为“未解析的引用”和函数之外。
Python 中局部变量类型标注的行为差异是设计使然,并符合该语言处理名称解析的方式。 让我们来分析一下原因。
1. 作用域
-
全局作用域: 当在全局作用域(如的示例中
a: something = 0
)中编写类型标注时,Python 会将其视为对尚未定义的名称的常规引用。由于 Python 在执行之前进行名称解析,因此会立即引发NameError
。 -
局部作用域: 在函数内部,类型标注在函数定义时不进行评估。这是因为 Python 使用了一种称为“延迟标注评估”的机制。类型标注仅在需要时进行评估,例如使用类型提示工具或在运行时进行类型检查。
2. 标注的目的
类型标注的主要目的是提供有关的代码的提示信息。它们并非旨在在运行时强制执行严格的类型检查(除非使用像 MyPy 这样的工具)。因此,函数内部缺少类型定义不会导致运行时错误。
3. 为什么不在函数内部引发
NameError
?
- 前向引用: 可能在函数稍后定义了该类型,或者它可能来自尚未导入的模块。在定义时引发错误会妨碍前向引用和循环依赖。
- 动态类型: Python 是一种动态类型语言,允许在运行时灵活地更改变量的类型。在函数定义时强制执行严格的类型检查与 Python 的动态性质相冲突。
4. 潜在的缺点和缓解措施
是正确的,这种行为可能会导致在函数中忽略未定义的类型。但是,可以使用以下方法来缓解这种情况:
- 类型检查工具: 使用 MyPy 等工具在的代码上执行静态类型检查。MyPy 会捕获到这些未定义的类型并发出错误。
- Linters: 使用 PyCharm 或 VS Code 等支持类型标注的 linter。它们通常会突出显示未定义的类型作为警告。
总而言之, Python 中局部变量类型标注的行为差异是设计使然,并且符合该语言的动态性质和标注的主要目的。了解此行为并利用类型检查工具可以帮助编写更健壮、更易于维护的代码。
标签:python,python-3.6,python-typing From: 41291892