这种奇怪的冒号行为在做什么?

时间:2018-01-18 14:23:41

标签: python python-3.x

我使用的是Python 3.6.1,我遇到了一些非常奇怪的东西。我有一个简单的字典分配拼写错误,花了我很长时间才找到。

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

输出

{}

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

我也认为如果声明可能是单行,但这也不应该是正确的语法。

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

我很困惑。发生了什么事?

1 个答案:

答案 0 :(得分:87)

您不小心写了一个语法正确的变量注释。该功能是在Python 3.6中引入的(参见PEP 526)。

虽然变量注释被解析为annotated assignment的一部分,但赋值语句是可选

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

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

  • context["a"]是注释目标
  • 2是注释本身
  • context["a"]未经初始化

PEP声明“注释的目标可以是任何有效的单一分配目标,至少在语法上(由类型检查器决定如何处理)”,这意味着密钥不需要存在以进行注释(因此没有KeyError)。以下是原始PEP的一个例子:

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

通常,注释表达式应该计算为Python类型 -  毕竟主要使用注释是类型提示,但它没有强制执行。无论结果的类型或值如何,注释都可以是任何有效的 Python表达式。

正如您所看到的,此时类型提示非常宽松且很少有用,除非您有一个静态类型检查器,例如mypy