这种奇怪的结肠行为在做什么?

问题:这种奇怪的结肠行为在做什么?

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

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

输出量

{}

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

我还认为它可能是if语句的一行,但这也不应该是正确的语法。

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

我很困惑。到底是怎么回事?

I am using Python 3.6.1, and I have come across something very strange. I had a simple dictionary assignment typo that took me a long time to find.

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

Output

{}

What is the code context["a"]: 2 doing? It doesn’t raise a SyntaxError when it should IMO. At first I thought it was creating a slice. However, typing repr(context["a"]: 2) raises a SyntaxError. I also typed context["a"]: 2 in the console and the console didn’t print anything. I thought maybe it returned None, but I’m not so sure.

I’ve also thought it could be a single line if statement, but that shouldn’t be the right syntax either.

Additionally, context["a"] should raise a KeyError.

I am perplexed. What is going on?


回答 0

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

尽管将变量注释解析为带注释的赋值的一部分,但是赋值语句是可选的

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之类的静态类型检查器,否则类型提示非常宽松,很少有用。

You have accidentally written a syntactically correct variable annotation. That feature was introduced in Python 3.6 (see PEP 526).

Although a variable annotation is parsed as part of an annotated assignment, the assignment statement is optional:

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

Thus, in context["a"]: 2

  • context["a"] is the annotation target
  • 2 is the annotation itself
  • context["a"] is left uninitialised

The PEP states that “the target of the annotation can be any valid single assignment target, at least syntactically (it is up to the type checker what to do with this)”, 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.

Normally, the annotation expression should evaluate to a Python type — after all the main use of annotations is type hinting, but it is not enforced. The annotation can be any valid Python expression, regardless of the type or value of the result.

As you can see, at this time type hints are very permissive and rarely useful, unless you have a static type checker such as mypy.