Python の AST では、ブール式を次のように定義しています。
BoolOp(boolop op, expr* values)
に似ていると予想していましたがBinOp
、 aleft
と a のright
値があります。
AST が 2 以外の値を持つコード例を誰か教えてもらえますか?
編集:
どうやらx and y and z
3つの値になります。ですから、言い換えてみましょう:
BoolOp
これが 2 つのネストされた式としてモデル化されないのはなぜですか?
Python の AST では、ブール式を次のように定義しています。
BoolOp(boolop op, expr* values)
に似ていると予想していましたがBinOp
、 aleft
と a のright
値があります。
AST が 2 以外の値を持つコード例を誰か教えてもらえますか?
編集:
どうやらx and y and z
3つの値になります。ですから、言い換えてみましょう:
BoolOp
これが 2 つのネストされた式としてモデル化されないのはなぜですか?
a and b and c
は、Python パーサーによって三項接続詞と見なされます。
>>> e = ast.parse('''a and b and c''').body[0].value
>>> e.op
<_ast.And object at 0x254d1d0>
>>> e.values
[<_ast.Name object at 0x2d9ba50>, <_ast.Name object at 0x2d9ba90>, <_ast.Name object at 0x2d9bad0>]
括弧は再帰的な二項論理積として解析することを強制しますが:
>>> ast.parse('''a and (b and c)''').body[0].value.values
[<_ast.Name object at 0x2d9b990>, <_ast.BoolOp object at 0x2d9bb10>]
これがなぜなのかわかりません。いずれにせよ、BoolOp
CPython ソース コードの単体テストによると、a は 2 つ未満の子を持つことはできません。
最初は最適化だと思っていましたが、;a and b and c
と完全に同等です。a and (b and c)
それらは同一のバイトコードを生成します:
>>> def f(a, b, c):
... return a and b and c
...
>>> def g(a, b, c):
... return a and (b and c)
...
>>> from dis import dis
>>> dis(f)
2 0 LOAD_FAST 0 (a)
3 JUMP_IF_FALSE_OR_POP 15
6 LOAD_FAST 1 (b)
9 JUMP_IF_FALSE_OR_POP 15
12 LOAD_FAST 2 (c)
>> 15 RETURN_VALUE
>>> dis(g)
2 0 LOAD_FAST 0 (a)
3 JUMP_IF_FALSE_OR_POP 15
6 LOAD_FAST 1 (b)
9 JUMP_IF_FALSE_OR_POP 15
12 LOAD_FAST 2 (c)
>> 15 RETURN_VALUE