如何动态修改字符串变量值及为表达式变量动态赋值后执行eval
问题2:动态为数学表达式变量赋值并执行
eval() 你的思路是对的,核心是提取变量名→绑定变量值→安全执行表达式,但直接把值赋值给全局/局部变量不太优雅(还可能污染命名空间),更安全可控的方式是把变量存在字典里,传给eval()的局部命名空间参数。
下面是完整的实现步骤和代码:
步骤1:提取表达式中的变量名
用正则表达式re.findall(r"\w+", s)可以提取所有字母数字下划线组成的变量名,注意加r表示原生字符串,避免转义问题。
步骤2:绑定变量值
假设somefunction()返回的是和变量名顺序对应的元组,我们可以用zip()把变量名和值配对成字典。
步骤3:安全执行表达式
调用eval()时,把变量字典作为第三个参数(局部命名空间)传入,第一个参数传空字典可以避免使用全局变量,更安全。
完整代码示例:
import re def somefunction(): # 模拟返回变量值,顺序要和提取的变量名对应(这里对应a, b, c) return (True, False, True) # 你的表达式字符串 s = "a&(b|c)" # 1. 提取所有变量名 var_names = re.findall(r"\w+", s) print("提取到的变量名:", var_names) # 输出:['a', 'b', 'c'] # 2. 获取变量值并构建字典 var_values = somefunction() var_dict = dict(zip(var_names, var_values)) # 3. 执行表达式并获取结果 result = eval(s, {}, var_dict) print("表达式执行结果:", result) # 输出:True(因为True & (False | True) = True)
注意事项:
- 安全性:如果你的表达式来自不可信的外部输入,绝对不要用
eval(),因为它会执行任意代码,存在严重的安全风险。 - 正则优化:如果表达式里包含函数名(比如
"max(a,b)"),re.findall(r"\w+", s)会把max也当成变量提取,这时候可以调整正则为r"\b[a-zA-Z_]\w*\b",并过滤掉内置函数名,或者根据你的实际场景调整匹配规则。
内容的提问来源于stack exchange,提问作者JaySabir
相关产品推荐
相关产品推荐

