Python ast名称节点替换删除括号

0 投票
1 回答
640 浏览
提问于 2025-04-17 22:34

我正在尝试用Python开发一个方程解析器,最终可以处理子公式。我的想法是,用户可能会给出一个方程,其中的变量并不是全部已知的。但是,有些子公式可能会为这些未定义的变量提供定义。

程序应该把未知的变量替换成子公式。根据@ebarr在这里提供的帮助,我进一步发展了这个想法,但因为一个愚蠢的问题而失败:当我用子公式替换一个变量时,ast.parse总是会删除左右括号,这样就导致最终的公式不正确。

有没有什么办法可以保留括号呢?

import ast

list_know_var = ['vx', 'vy', 'vz', 'c']
equation = 'M = V  * V / c'
know_equations = {'V': 'vx + 1.'}

# initial equation
parsed_equation = ast.parse(equation)

# the class that automatically dives into the nodes of the AST
# to check for all variables definition
class AdaptEquation(ast.NodeTransformer):
    def visit_name(self, node):
        # checking that the variable is know
        if node.id not in list_know_var:
            if node.id in know_equations.keys():
                node = ast.parse(know_equations[node.id]).body[0].value
        return node

# adapted equation
AdaptEquation().visit(parsed_equation)

# and its human readable expression
import codegen
print('expected equation: M = (vx + 1) * (vx + 1) / c')
>>> expected equation: M = (vx + 1) * (vx + 1) / c
print('adapted equation: ', codegen.to_source(parsed_equation))
>>> adapted equation:  M = vx + 1.0 * vx + 1.0 / c

1 个回答

1

我找到了解决办法。用 Astor 替代 Codegen。虽然我很喜欢 Codegen,但我得说它有点问题。Astor 是在 Codegen 的基础上开发的,更新且功能更多。下面是一个使用 Astor 的例子:

import astor
import ast
test_code = "x=1-(x+y)"
abstract_syntax_tree = ast.parse(test_code)
print(astor.to_source(abstract_syntax_tree))
print('done')

#output
#x = (1 - (x + y))
#done

撰写回答