gpt4 book ai didi

python - 用 AST python 表达式中的实际值替换变量名

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:59 25 4
gpt4 key购买 nike

我有一个像这样用变量形式描述的表达式

's1*3 - (s2-s1)*1'

我已经给了s1和s2的值,可以根据需要改变

我可以使用 python ast模块通过替换相应的 s1 和 s2 值(s1 = 20,s2=30)来评估此表达式

import ast
import operator as op

operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul,
ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor,
ast.USub: op.neg}

def eval_(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return operators[type(node.op)](eval_(node.left), eval_(node.right))
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](eval_(node.operand))
else:
raise TypeError(node)

>>> str1 = '20*3 - (30-20)*1'
>>> node = ast.parse(str1, mode='eval')
>>> eval_(node.body)
50

我应该如何评估这个表达式而不需要用它们的实际值替换变量。

谢谢

最佳答案

要计算表达式,您可以使用 NodeVisitor:

from ast import NodeVisitor

class EvalVisitor(NodeVisitor):
def __init__(self, **kwargs):
self._namespace = kwargs

def visit_Name(self, node):
return self._namespace[node.id]

def visit_Num(self, node):
return node.n

def visit_NameConstant(self, node):
return node.value

def visit_UnaryOp(self, node):
val = self.visit(node.operand)
return operators[type(node.op)](val)

def visit_BinOp(self, node):
lhs = self.visit(node.left)
rhs = self.visit(node.right)
return operators[type(node.op)](lhs, rhs)

def generic_visit(self, node):
raise ValueError("malformed node or string: " + repr(node))

然后您可以将此评估器用作

v = EvalVisitor(s1=20, s2=30)
print(v.visit(node.body))

这就是 ast.literal_eval 的大致实现方式,增加了允许您在非数字表达式求值和不求值的情况下传递值的功能。

顺便说一下,这个operators 字典的技巧不错。我会复制那个:)

关于python - 用 AST python 表达式中的实际值替换变量名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26398179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com