wim*_*wim 8 python abstract-syntax-tree
比较运算符可以在python中链接,因此例如x < y < z应该给出结果(x < y) and (y < z),除了y保证只评估一次.
此操作的抽象语法树如下所示:
>>> ast.dump(ast.parse('0 < 1 < 2'), annotate_fields=0)
'Module([Expr(Compare(Num(0), [Lt(), Lt()], [Num(1), Num(2)]))])'
Run Code Online (Sandbox Code Playgroud)
漂亮印刷:
Module
Expr
Compare
Num
Lt
Lt
Num
Num
Run Code Online (Sandbox Code Playgroud)
但它似乎解析为类似的东西0 < < 1 2,我不知道如何将其与某些类似的逻辑结果相协调0 < 1 and 1 < 2.
如何解释链式比较的ast?
实际上在ast文档中提到了这背后的原因
Run Code Online (Sandbox Code Playgroud)-- need sequences for compare to distinguish between -- x < 4 < 3 and (x < 4) < 3 | Compare(expr left, cmpop* ops, expr* comparators)
如果它被评估为两个单独的比较,像这样
Module(Expr(Compare(Compare(Num(0), [Lt()], [Num(1)]), [Lt()], [Num(2)]))])
Run Code Online (Sandbox Code Playgroud)
然后它实际上将第一次比较的布尔结果与第二次比较中的整数进行比较.
像这样的东西是行不通的
-5 < -4 < -3
Run Code Online (Sandbox Code Playgroud)
因为它会被评估为
(-5 < -4) < -3
Run Code Online (Sandbox Code Playgroud)
评估为
1 < -3
Run Code Online (Sandbox Code Playgroud)
相反,它被作为单个表达式处理.这个Compare操作的python实现看起来像这样
def Compare(left, ops, comparators):
if not ops[0](left, comparators[0]):
return False
for i, comparator in enumerate(comparators[1:], start=1):
if not ops[i](comparators[i-1], comparator):
return False
return True
Run Code Online (Sandbox Code Playgroud)