首页 > Python基础教程 >
-
PEP 526 变量注解的语法 -- Python官方文档译文 [原创](2)
这样会要求语法解析器变得更为复杂,
class
关键字也会把简单的语法高亮显示程序弄糊涂。无论如何,都需要 ClassVar
把类变量存储到 __annotations__
中去,因此就选用了更简单的语法。
完全不用 ClassVar
:
mypy 无法区分类变量和实例变量,可貌似也能混的不错,因此才会有这个提案。但是类型检查程序利用这些附加信息能够干很多有用的工作,比如标记出由实例对类变量的意外赋值。这种赋值会创建实例变量,将类变量遮掩起来(shadow)。类型检查程序还可以将实例变量标记为默认可修改,声明众所周知的风险。
用 ClassAttr
替换 ClassVar
:
ClassVar 更为合适,主要是因为类的属性可以有很多,如方法、描述符等。但是从概念上讲,只有特定的属性才是类变量(或常量)。
不对注解进行解析求值,只视其为字符串:
对函数注解始终都会进行解析求值,这样就会与其表现不一。尽管未来可能会重新考虑,但在 PEP 484 中已决定应该将其作为单独的 PEP 进行规范。
在类的文档字符串中对变量类型进行注解
许多项目已经应用了各种文档字符串规范,一致性往往不太好,通常还不符合 PEP 484 的注解语法。并且也还是需要比较复杂的特殊语法解析器。本 PEP 的目标正是要与第三方类型检查工具协作,如此目标就会落空。
将 __annotations__
实现为描述符
这条提案是为了禁止将 __annotations__
设为除字典和 None
之外的东西。Guido 拒绝了这个提案,认为没有必要。如果试图将 __annotations__
修改为字典映射之外的任何东西,都会引发 TypeError。
将纯注解视同全局或非局部的:
这条提案希望,出现在函数体内的无赋值注解不应进行任何解析求值。与之相反,本 PEP 表明,如果注解目标比单个名称复杂,则应在函数体内的目标出现位置对其“左值部分”进行解析求值,以强制确认其是否已经定义。例如在以下示例中:
def foo(self):
slef.name: str
slef
就应该被解析求值,这样若是其尚未定义(本例中貌似就是如此:-)),运行时将会引发错误。这样就与带初值时的表现更为一致,因此应该能减少意外情况的发生。还有一点请注意,如果注解目标是 self.name
(这次拼写正确了:-)),那么做过优化的编译器并不保证会对 self
进行解析求值,只要能够证明其一定是已定义的即可。
向下兼容性(Backwards Compatibility)
本 PEP 完全向下兼容。
实现代码(Implementation)
适用于 Python 3.6 的已实现代码可在以下 GitHub repo 中找到:https://github.com/ilevkivskyi/cpython/tree/pep-526。