这种奇怪的结肠行为是怎么回事?

我正在使用 Python3.6.1,我遇到了一些非常奇怪的情况。我有一个简单的字典作业打错了,我花了很长时间才找到。

context = {}
context["a"]: 2
print(context)

输出

{}

代码 context["a"]: 2在做什么?它没有提出一个 SyntaxError当它应该 IMO。一开始我以为它是在切片。但是,键入 repr(context["a"]: 2)会引发 SyntaxError。我还在控制台中输入了 context["a"]: 2,但控制台没有打印任何内容。我想也许它返回 None,但我不那么肯定。

我还认为它可以是一个单独的 if 语句,但这也不应该是正确的语法。

此外,context["a"]应该提高 KeyError

我很困惑,这是怎么回事?

9530 次浏览

您不小心编写了一个语法正确的 变量注释变量注释,这个特性是在 Python 3.6中引入的(参见 PEP 526)。

虽然可变注释被解析为 带注释的作业的一部分,但赋值语句是 可以选择:

annotated_assignment_stmt ::=  augtarget ":" expression ["=" expression]

因此,在 context["a"]: 2

  • context["a"]是注释目标
  • 2 is the annotation itself
  • context["a"]没有初始化

The PEP states that 注释的目标可以是任何有效的单个赋值目标,至少在语法上是如此(这取决于类型检查器如何处理), which means that the key doesn't need to exist to be annotated (hence no KeyError). Here's an example from the original PEP:

d = {}
d['a']: int = 0  # Annotates d['a'] with int.
d['b']: int      # Annotates d['b'] with int.

通常,注释表达式 应该的计算结果是 Python 类型—— 毕竟,注释的主要用途是类型提示,但它并不是强制的。注释可以是任何 有效 Python 表达式,而不管结果的类型或值如何。

正如您可以看到的,此时类型提示非常宽松,而且很少有用,除非您有一个静态类型检查器,如 我的天

这些注释自动存储在 __annotations__中,__annotations__是一个 dict。对于 x: yy必须是一个有效的表达式,也就是 y,或者 :右边的任何东西,都必须求值。另一方面,x,必须,至少能够是一个关键,从而散列。

此外,LHS 不能是一个集合,因为集合是不可散列的, >>> {2}: 8

SyntaxError: illegal target for annotation

也没有清单: >>> [2]: 8

[2]: 8 SyntaxError: only single target (not list) can be annotated

也不是元组:

>>> (2,3): 8 (2,3): 8 SyntaxError: only single target (not tuple) can be annotated