用 Perl 的 B::Concise 之类的东西转储 Python optree?
Dumping the Python optree with something like Perl's B::Concise?
Perl 有一个叫做 B::Concise 的东西,我们可以将它与 -MO=Concise
一起使用
perl -MO=Concise -e "!$a&&!$b"
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <1> not vK/1 ->7
4 <|> or(other->5) sK/1 ->6
- <1> ex-not sK/1 ->4
- <1> ex-rv2sv sK/1 ->-
3 <#> gvsv[*a] s ->4
- <1> ex-not sK/1 ->6
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*b] s ->6
有没有办法让 Python 以文本可读的形式转储 optree?
我能够使用 dis
模块做到这一点
import dis;
a = 5;
def f():
a = a+1
print "foo"
print dis.dis(f);
输出,
7 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 STORE_FAST 0 (a)
8 10 LOAD_CONST 2 ('foo')
13 PRINT_ITEM
14 PRINT_NEWLINE
15 LOAD_CONST 0 (None)
18 RETURN_VALUE
None
而不是从dis
, you can get the AST from ast
获取字节码:
>>> import ast
>>> ast.dump(ast.parse("a = a+1").body[0])
"Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=1)))"
问题中的例子:
>>> ast.dump(ast.parse("not a and not b").body[0])
"Expr(value=BoolOp(op=And(), values=[UnaryOp(op=Not(), operand=Name(id='a', ctx=Load())), UnaryOp(op=Not(), operand=Name(id='b', ctx=Load()))]))"
定义示例:
>>> ast.dump(ast.parse("""def f():
... a = a+1
... print \"foo\"""").body[0])
"FunctionDef(name='f', args=arguments(args=[], vararg=None, kwarg=None, defaults=[]), body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=1))), Print(dest=None, values=[Str(s='foo')], nl=True)], decorator_list=[])"
Perl 有一个叫做 B::Concise 的东西,我们可以将它与 -MO=Concise
perl -MO=Concise -e "!$a&&!$b"
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <1> not vK/1 ->7
4 <|> or(other->5) sK/1 ->6
- <1> ex-not sK/1 ->4
- <1> ex-rv2sv sK/1 ->-
3 <#> gvsv[*a] s ->4
- <1> ex-not sK/1 ->6
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*b] s ->6
有没有办法让 Python 以文本可读的形式转储 optree?
我能够使用 dis
模块做到这一点
import dis;
a = 5;
def f():
a = a+1
print "foo"
print dis.dis(f);
输出,
7 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 STORE_FAST 0 (a)
8 10 LOAD_CONST 2 ('foo')
13 PRINT_ITEM
14 PRINT_NEWLINE
15 LOAD_CONST 0 (None)
18 RETURN_VALUE
None
而不是从dis
, you can get the AST from ast
获取字节码:
>>> import ast
>>> ast.dump(ast.parse("a = a+1").body[0])
"Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=1)))"
问题中的例子:
>>> ast.dump(ast.parse("not a and not b").body[0])
"Expr(value=BoolOp(op=And(), values=[UnaryOp(op=Not(), operand=Name(id='a', ctx=Load())), UnaryOp(op=Not(), operand=Name(id='b', ctx=Load()))]))"
定义示例:
>>> ast.dump(ast.parse("""def f():
... a = a+1
... print \"foo\"""").body[0])
"FunctionDef(name='f', args=arguments(args=[], vararg=None, kwarg=None, defaults=[]), body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=1))), Print(dest=None, values=[Str(s='foo')], nl=True)], decorator_list=[])"