【问题标题】:Unexpected valid syntax in annotated assignment expression带注释的赋值表达式中出现意外的有效语法
【发布时间】:2020-06-04 01:36:49
【问题描述】:

显然(并且至少对我来说令人惊讶),这是 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 时才被发现。

无论如何,我主要只是对意图感到好奇,但如果发现我发现了一个实际的语法错误,我也会非常兴奋。

【问题讨论】:

  • 预期的用例类似于(请原谅没有缩进):x: int; if blah: x = 3 else: x = 2 or 作为类的注释,它只是像那

标签: python syntax type-annotation


【解决方案1】:

由于解析器的原因,它被归类为带注释的赋值。如果有单独的 annotation 和 annassign 规则,Python 的 LL(1) 解析器在看到冒号时将无法判断它应该解析哪一个。

【讨论】:

  • 这是有道理的。您的答案中隐含的事实是这是有效的语法。不幸的是,由于我的项目必须与较旧的 Python 版本兼容,因此我无法深入探索这些类型的注释。
猜你喜欢
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
相关资源
最近更新 更多