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

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

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

x: 10

这到底是怎么回事? 我检查了一下,用 ast 模块,并得到了以下内容。

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

好吧,所以这是一个注释的任务。我查了一下 语法参考 并看到它对应的是这个规则。

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

这对我来说没有太大意义 如果它是一个注释的 任务那么,为什么表达式的赋值部分是可选的?如果表达式的赋值部分不存在,这可能意味着什么?这不是很奇怪吗?

在这里,我想说的是,如果表达式中的赋值部分不存在,那么,为什么表达式的赋值部分是可选的呢?annasign 节点只在一条规则中被引用。

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

在该层的其他可能的投影中,都需要某种赋值表达式(augassign 是一个象征性的东西,如 +=). 那么,为什么它是可选的 annassign?

我想,这可能是一个裸名表达式的注释版本(即只有 x),但这真的很让人困惑。我对静态类型检查器不是很熟悉,但他们能不能利用这样的注释?

更有可能是有意为之,但这看起来有点像一个bug。这有点问题,因为有可能写出这样语法上有效但完全无意义的代码。

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

我最近在自己的代码中也犯了一个类似的错误 当我把一个... ... dict 表示法变成独立的变量,当我的测试管道在Python 3.5环境中运行并产生一个 SyntaxError.

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

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

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

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