带注释的赋值表达式中的意外有效语法

问题描述 投票:1回答:1

显然(至少对我来说是令人惊讶的是,这在Python 3.6+中是一个完全有效的表达式:

x: 10

这是怎么回事?我使用ast模块将其签出,并得到了以下内容:

[ins] In [1]: ast.parse('x: 10').body
Out[1]: [<_ast.AnnAssign at 0x110ff5be0>]

好的,这是一个带注释的作业。我查看了grammar reference,发现它符合此规则:

annassign: ':' test ['=' test]

对我来说这没有多大意义。如果是带注释的assignment,那么为什么表达式的赋值部分是可选的?如果表达式的赋值部分不存在,可能意味着什么?真的不奇怪吗?

annasign节点仅在一个规则中被引用:

expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
                     ('=' (yield_expr|testlist_star_expr))*)

在该级别上的每个其他可能的投影中,需要某种分配表达式(augassign是类似于+=的标记)。那么,为什么annassign是可选的?

我想这可能是裸名表达式的带注释版本(即x),但这确实很令人困惑。我对那里的静态类型检查器不太熟悉,但是他们可以使用这样的注释吗?

[很有可能是故意的,但这似乎是一个错误。这有点问题,因为可以这样编写语法上有效但完全没有意义的代码:

a = 1
b = 2
c: 3 # see what I did there? oops!
d = 4

[我最近在将dict表示转换为单独的变量时,在自己的代码中犯了类似的错误,并且仅当我的测试管道在Python 3.5环境中运行并产生了SyntaxError时,才被发现。

无论如何,我基本上只是对意图感到好奇,但是很高兴发现我发现了一个实际的语法错误。

显然(至少对我来说是令人惊讶的,这在Python 3.6+中是一个非常有效的表达式:x:10这是怎么回事?我使用ast模块将其签出,并得到以下信息:[ins] In ...

python syntax type-annotation
1个回答
1
投票

出于解析器原因,它被归类为带注释的作业。如果存在单独的annotationannassign规则,则Python的LL(1)解析器将无法识别看到冒号时应该解析的是哪个。

© www.soinside.com 2019 - 2024. All rights reserved.