Python AST工作工具箱
项目描述
Python AST工作工具箱
pip install ast_tools
有用参考资料
Passes
ast_tools提供了一系列用于重写函数和类的passes(也可以在模块级别工作,但不存在此类pass)。通过apply_passes装饰器应用passes。
@apply_passes([pass1(), pass2()])
def foo(...): ...
每个pass将AST、环境和元数据作为参数,并返回(可能)修改后的版本。apply_passes通过首先查找装饰对象的ast,并尝试从调用站点收集局部和全局变量来构建环境,开始一系列重写。
所有重写运行完毕后,apply_passes将序列化和执行重写的ast。
已知问题
收集AST
apply_passes
依赖于inspect.getsource
来获取装饰定义的源代码(然后解析以获取初始ast)。然而,inspect.getsource
有很多限制。
收集环境
apply_passes
尽力推断环境,但无法完全正确地执行此操作。鼓励用户明确传递环境。
@apply_passes(..., env=SymbolTable(locals(), globals()))
def foo(...): ...
包装apply_passes装饰器
apply_passes
装饰器不能被包装。
作为装饰器是它们应用到的对象的AST的一部分,它们必须在执行之前从重写的AST中移除。如果没有移除,重写将无限递归,因为
@apply_passes([...])
def foo(...): ...
将变成
exec('''\
@apply_passes([...])
def rewritten_foo(...): ...
''')
注意:这将调用apply_passes([...])
在rewritten_foo
上
为了避免这种情况,apply_passes
装饰器从装饰器列表中过滤掉自己。然而,如果装饰器包装在另一个装饰器内部,这将失败。
内部装饰器被多次调用
在重写组之前应用装饰器将多次调用。请参阅https://github.com/leonardt/ast_tools/issues/46以获取详细解释。为了避免这种情况,鼓励用户尽可能将重写放在最内层的装饰器中。
宏
循环展开
使用以下模式展开循环
for <var> in ast_tools.macros.unroll(<iter>):
...
<iter>
应该是一个可迭代对象,它生成整数(例如 range(8)
),在定义时可以评估(可以在函数定义的作用域中引用变量)。
例如,
from ast_tools.passes import apply_passes, loop_unroll
@apply_passes([loop_unroll()])
def foo():
for i in ast_tools.macros.unroll(range(8)):
print(i)
会被重写为
def foo():
print(0)
print(1)
print(2)
print(3)
print(4)
print(5)
print(6)
print(7)
您还可以使用整数的列表,这里有一个也使用外部作用域中定义的变量引用的例子。
from ast_tools.passes import apply_passes, loop_unroll
j = [1, 2, 3]
@apply_passes([loop_unroll()])
def foo():
for i in ast_tools.macros.unroll(j):
print(i)
变为
def foo():
print(1)
print(2)
print(3)
内联 If 语句
此宏允许您在函数定义时评估 if
语句,因此重写后的函数将移除标记为“内联”的 if
语句,并根据在定义的封装作用域中评估的条件替换为选择的分支。if
语句通过使用形式 if inline(...):
进行标记,其中 inline
从 ast_tools.macros
包中导入。if
语句不匹配此模式将被重写逻辑忽略。
以下是一个示例
from ast_tools.macros import inline
from ast_tools.passes import apply_passes, if_inline
y = True
@apply_passes([if_inline()])
def foo(x):
if inline(y):
return x + 1
else:
return x - 1
import inspect
assert inspect.getsource(foo) == f"""\
def foo(x):
return x + 1
"""
项目详情
下载文件
下载您平台的文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。