带注释的赋值表达式中出现意外的有效语法
Unexpected valid syntax in annotated assignment expression
显然(至少对我来说令人惊讶),这是 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,那么为什么表达式的赋值部分是可选的?如果表达式的赋值部分不存在,这可能意味着什么?真的不是st运行ge吗?
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
.
无论如何,我主要只是对意图感到好奇,但如果发现我发现了一个实际的语法错误,我也会非常兴奋。
出于解析器的原因,它被归类为带注释的作业。如果有单独的 annotation
和 annassign
规则,Python 的 LL(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,那么为什么表达式的赋值部分是可选的?如果表达式的赋值部分不存在,这可能意味着什么?真的不是st运行ge吗?
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
.
无论如何,我主要只是对意图感到好奇,但如果发现我发现了一个实际的语法错误,我也会非常兴奋。
出于解析器的原因,它被归类为带注释的作业。如果有单独的 annotation
和 annassign
规则,Python 的 LL(1) 解析器在看到冒号时将无法判断它应该解析哪一个。