3

Python の AST では、ブール式を次のように定義しています。

BoolOp(boolop op, expr* values)

に似ていると予想していましたがBinOp、 aleftと a のright値があります。

AST が 2 以外の値を持つコード例を誰か教えてもらえますか?

編集:

どうやらx and y and z3つの値になります。ですから、言い換えてみましょう:

BoolOpこれが 2 つのネストされた式としてモデル化されないのはなぜですか?

4

1 に答える 1

6

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>]

これがなぜなのかわかりません。いずれにせよ、BoolOpCPython ソース コードの単体テストによると、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        
于 2013-10-15T10:07:03.083 に答える