何时以及如何评估Python注释

2021-06-10 17:42:32

LWN订阅者已为您提供以下订阅内容。成千上万的订阅者依赖LWN了解Linux和自由软件社区的最佳新闻。如果您喜欢本文,请考虑订阅LWN。感谢您访问lwn.net!

Python的注释迟到了派对;它们被引入了inpython 3作为将信息附加到描述其参数和return值的函数的方法。虽然该机制对Python函数添加了向Python函数添加了型信息的显而易见的应用程序,但TheanNotations的标准解释来到了类型提示。但是评估功能定义时间的注释,尤其是关于转发类型名称的转发引用,所以Python增强提案(PEP)创建以推迟他们,直到需要它们。 PEP描述的行为是在即将到来的Python 3.10版本中设置的默认情况,但不知道;默认评估的推迟本身就被推迟到淘汰的淘汰内容。

正如可能被猜到的那样,有点纠结,这将需要一些人以充分了解事物。 2006年,PEP 3107("函数注释")被用于Python 3拍摄与函数&#39相关联的任意表达式的值; sarguments及其返回值。 __annotations__MicticumbyOceActions,然后包含该数据。来自PEP的一个例子是有效的,偶数它有点学习:例如,以下注释:将导致__annotations__映射返回键的映射,因为它不能与Aparameter的名称冲突;任何使用返回作为参数名称的尝试都会导致语法交替。

通过PEP:&#34的注释相关的价值观的解释是专门从事:" [...]此PEP不会尝试介绍一种标准语义,即使是内置类型。这项工作将留给第三方图书馆。"这一切都是用PEP 484("类型提示")更改,这是2015年为Python 3.5采用的;它为标准库添加了一个键入为提供"标准的词汇和基线工具"用于型注释。它没有改变注释的特性,也没有添加任何运行时类型检查,它只是用静态类型检查器使用的类型信息。使用PEP 526("变量注释语法和变量注释语法的Variable Annotations。 #34;),它出现在Python 3.6中。

然而,使用这些注释遇到了一些问题。对于一个,ForwardReferents尚未定义的类型需要使用StringLiterals,而不是类型名称:例如,以下代码(简单二进制树木图的开始)不起作用:要解决此问题,我们写入:字符串文字应该包含有效的Python表达式(即,编译(点亮,''' eval')应该是有效的代码对象),并且一旦模块完全加载,它就不会出现错误。

另一个问题是评估这些注释需要偿还,因此所有程序都支付了注释的价格,即使他们不需要。此外,键入检查不会在运行时完成,但每次导入Amodule都会评估潜在的复杂类型注释,这使得无需实际增益。

提出的问题提出了PEP 563("推迟评估注释")。它的目标是,正如那样暗示,就是推迟评估注释,直到他们真正需要;相反,它们将作为字符串存储在__annotations__中。对于静态类型检查器,如果他们正在处理源代码,因此无论如何都没有区别,但如果在运行时需要注释,则需要留下返回 - 那个问题开始裁剪的地方。

Warning: Can only detect less than 5000 characters

一般来说,响应在1月份对PEP有利。 Guido Van Rossum,谁发起了暗示的暗示当他是仁语的仁语法时,似乎有利于对这个想法有所了解,并建议进一步的改进。Suchase Pep 563作者ŁukaszLanga,也表示支持:" iLike使用预先设置的codebject对_ annotations__的聪明懒惰评估。"

尽管如此,那些东西的东西待命了。在哪里。分析了一个Proddingor 2,黑斯廷斯并没有邮政于4月11日邮政649。这是漂亮的胶水3.10schedule,它具有第一个测试版(因此冻结)来到马涅3. van rossum hevivenup在临时在Pep 649上。事实上,他似乎已准备写了类型的注释:但是我认为它是接受诠释的时间是fortypes - PEP 3107的意图是为了尝试不同的类型的类型,并且实验导致成功采用特定的语法,以便彻底成功。

但是注释已经长时间的语言的一部分,除了静态类型检查器的型暗示中,其他函数的案例很长一段时间;黑斯廷斯现在揭示他们删除它们是有意义的:我很高兴暗示了一篇的提示已经找到了成功,但我没有看到为什么这意味着它"因此,我们应该仅限于类型限制注释的使用提示&#34 ;.注释是Python的一个有用的通用功能,除了类型提示之外的合法用途。为什么会让Python更好地限制他们的使用?

虽然,van rossum,"打字是,对于许多人来说,一个非常重要的概念"但是使用相同的语法,用于类型信息,通常是未定义的,"其他东西"是令人困惑的。黑斯廷斯是一个不合情的,型提示是非常重要的,因为他们应该胜过其他用途:i'不确定我理解你的观点。你是说我们需要外带注释的通用功能,即自3.0自3.0以来一直在调节,并限制注释只是键入提示......因此,否则可能不会用于型提示的注释,他们的程序员必须弄清楚它的意思吗?我们需要从所有其他用例中表达功能,以便对一个用例借出清晰度?

van rossum说:"是的,'我如何看待它。"但他对黑斯廷斯的努力变化的努力出错了,他不满意:[...]诠释的妥协已经在制造很长一段时间里,与社区' s和sc' s [转向委员会的支持。您将使用PEP进程提出最后一个MinuteApTept​​,以便建议*恢复*该决定已经编写了Inpep 563并在主分支中实现。但是,你等待直到最后一分钟(特征冻结在三个星期内)和imo'重新为sc(谁可以和自己说话)尴尬。

有Python库在运行时使用类型的注释,但是,在第563次描述的情况下,在支持延迟评估的情况下,有一些运行搁浅。由于它看起来像PEP 563将成为默认(符合现有行为)3.10, Laightsome文库的开发人员有点恐慌。这导致了来自Samuel Colvin的StrintDent(和Githubissue),他们维护了PyDijordata验证库。 COLVIN LISTSA束在PYDANTED的同时出现的其他错误,注意:原因是复杂的原因,但基本上是键入的.GET_TYPE_HINTS()并不是一直拨打的零件,又没有做出众多的黑客我们' ve介绍tiptand解决它。即使键入_get_type_hints()也是有关的,它会比当前的语义或PEP 649中的速度慢 - PyDantics No.' t与推迟注释非常好,也许它永远不会。

虽然科幻&#39的基调被视为过度戏剧性的,也许有些分裂,事实证明,其他人遇到过一些这些问题。 Paul Ganssle指出了attrs包中的困难,attrspporting的特色(哪个灵感在Python 3.7中添加了DataClassesfeature的灵感),因为事情如何变为Awry。他建议一条道路向前ashwell:[...]我不会感到惊讶的是,如果PEP 563正在静静地扔在几个其他地方的作业中的扳手,我的投票是留下PEP 563选择直到至少3.11 andernthan又试图追求讨论和实施PEP 649。

沿途有更多的讨论,包括Langa' S外观" PEP 563在PEP 649&#34的光明中;和黑斯廷斯'圣常杂式寻找妥协的妥协职位,这些位置是试图找到一种方式,以找到一种方式"营地"还有关于鸭键入的方面讨论,Python静态键入生态系统等。但大多数情况下,似乎人们只是在等待指导委员会的声明的标记时间。

那个Camill 4月20日。鉴于时机,问题的性质,而且没有将语言锁定到可能不会留下长期的行为的行为,它可能并不大多是Thecouncil&#34的惊喜。踢了下来道路"一点点。它决定推迟制作PEP 563行为默认,直到最可爱的Python 3.11。它也推迟了PEP 649或任何其他替代品。

假设型注释只会通过典型类型的验钞,托马斯韦斯代表理事会表示:"有明显的现实世界,运行时间使用的型号被这一方式受到不利影响。" PyDant的现有用户(包括流行的Fastapi Web框架)将受到改变的影响,但是也可能在运行时使用的annotations尚未亮起。最不可思议的选择是回滚到Python 3.9行为,而是:我们需要继续讨论问题和潜在的解决方案,请在3.11之前推迟问题。 (对于记录,推迟更改进一步没有关闭表,例如,如果FinalDecision将评估的注释视为已弃用的功能,则在使用中使用Warnnings。)对于它的价值,SC也在考虑我们可以做些什么重新删除这样的东西,就像这样发生的事情,但这是一个分开的,而且是一个多面对面的。

对于一个可选的功能,支持静态键入和类型提示的支持在过去五年甚至在该语言的其他部分中展开了鼻子。争辩说,通用注释方法可以用于添加一些静态键入的支持,但我们可能会在提供更好地支持键入任何其他注释的任何其他用途的地方,这可能会产生更好的静态键入支持,这不是一个特别是粘附的任何其他用途。如果键入是保持可选的,并且提出的是asamant,它将不会,其他长期特征不应依靠,以便使可选用例更好地工作。

统称深呼吸并踩回考虑可能性是在此处的正确方法。也许有些折扣的人可以找到所有现有的用户 - 特别是边缘使用,他们的开发人员可能完全不稳定,即使可以容纳了地平线的变化 - 可以容纳。当然,这些结果最适合每个人。将压缩休息一年左右可能只是提供足够的空间来实现这一点。

[我要感谢Salvo Tomaselli给我们一个"抬头"关于这个主题。](登录到发表评论)