ast抽象语法树_Odoo 中随处可见的 AST

eccab5eff599230c5d68e53d62d1567b.png

在阅读 Odoo 的后台 Python 代码中,经常看到 AST 相关的代码,每次遇到这些代码都不自主跳过;不久前在 Conda Python 3.8 的新环境中,Odoo 12 竟然没有跑起来,抛出的异常在 AST 相关的位置上。

odoo.addons.base.models.qweb.QWebException: required field "posonlyargs" missing from arguments
Traceback (most recent call last):
File "odoo/odoo/addons/base/models/qweb.py", line 332, in compile
unsafe_eval(compile(astmod, '<template>', 'exec'), ns)
TypeError: required field "posonlyargs" missing from arguments
Error when compiling AST
TypeError: required field "posonlyargs" missing from arguments
Template: 173
Path: /templates/t/t/form/input[2]
Node: <input type="hidden" name="redirect" t-att-value="redirect"/>

从异常的信息来看是 AST 在处理 Node 的时候出现了问题,从上面的异常信息的最后一行可见。借着这个机会看看 Python AST 究竟是啥。

什么是 AST

AST 即抽象语法树,百度一个定义:

在计算机科学中,**抽象语法树**(**A**bstract **S**yntax **T**ree,AST),或简称**语法树**(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于 if-condition-then 这样的条件跳转语句,可以使用带有两个分支的节点来表示。

关于AST的Python 官方文档。

AST 模块可帮助 Python 应用程序处理 Python 抽象语法语法的树。 每个Python 版本都可能更改抽象语法。 该模块有助于以编程方式找出当前语法的外观。
通过将ast.PyCF_ONLY_AST作为标志传递给compile()内置函数,或使用此模块中提供的parse()帮助器,可以生成抽象语法树。 结果将是一棵对象树,其所有类均继承自ast.AST。 可以使用内置的compile()函数将抽象语法树编译为Python代码对象。

Odoo 借助 Python AST 在抽象语法树的层次动态构造 Python 程序,从而能够将 QWeb Template 中的语法映射成 Python 代码。通过直接构造 AST,然后再 Compile,再求值。从而能够在 QWeb 中使用 Python 的语法,在模板文件中直接使用Python代码逻辑。

AST 中的 Node 递归起来就是一个 Tree,每个节点就是 Node;ast.parse(code_string) 能把 Python 代码分析成 AST,Python 本身没有提供把 AST 变成 Python 代码的功能,有一些第三方库可以做这个事情。举个简单的例子:

>>> import ast
>>> ast.dump(ast.parse('-5'))
'Module(body=[Expr(value=UnaryOp(op=USub(), operand=Constant(value=5, kind=None)))], type_ignores=[])'
>>> 

上面的例子是给 ‘-5’ 这个常数构造 AST,其body 是一个 Expr,value 是一个 UnaryOp,operand 是 Constant。

再看一个:

>>> ast.dump(ast.parse('print("Hello World")'))
"Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Constant(value='Hello World', kind=None)], keywords=[]))], type_ignores=[])"
>>> 

这个Expr 就是一个 Call,Call 需要的参数是 func,args。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值