python - 如何将由其他地方定义的函数和变量构建的表达式传递给 exec() 或 eval()?
问题描述
我有一个项目需要在多个位置进行部署。每个位置的代码都必须相同,并在配置文件中定义自定义。大多数配置文件将是整数字典,但在某些情况下,表达式将包含代码中定义的函数。我eval()
用来解释包含这些表达式的文本,但我遇到了与范围相关的问题。我的第一次尝试包括以下代码行
temp_text="np.round(get_last_3_values_avg(data,'Qty',sku),decimals=0)"
new_val=eval(temp_text,globals())
其中get_last_3_values_avg
和变量在别处定义。此代码产生一个错误,指出变量未定义。我也试过
ex_st='def tempfun():\n\treturn '+temp_text
exec(ex_st)
a =tempfun
但这会产生相同的错误。我也尝试在文本字符串中定义一个变量而不是一个函数,但得到了相同的结果:
ex_st='var='+temp_text
exec(ex_st)
a =var
另一种尝试是尝试在 locals 字典中检索该函数:
ex_st='def tempfun():\n\treturn '+temp_text
loca={}
exec(ex_st,globals(),loca)
a = loca['tempfun']
但我得到的是函数而不是函数返回的值。我也尝试将变量传递给函数。为了解决这个问题,我尝试了一个 lambda 函数:
def outer(data,sku):
return lambda q: loca['tempfun'](data,sku)
temp=outer(data,sku)
wheretempfun
被修改为采用变量,但我遇到了同样的问题。有没有办法将一行代码读取为带有 exec 或 eval 的字符串,该字符串中的文本引用其他地方定义的变量和函数?我还应该提到,代码将在只有合格工程师才能访问的计算机上本地运行,因此有关安全问题的担忧eval()
很小。谢谢
解决方案
我同意配置文件中的允许代码很尴尬,应该更改,但我想说明问题的解决方案已经实现,以防其他人有同样的问题。解决方案是将代码嵌入到问题中所述的函数中:
ex_st='def tempfun():\n\treturn '+temp_text
loca={}
exec(ex_st,globals(),loca)
a = loca['tempfun']
然后正如 juanpa.arrivilla 解释的那样:
desired_value=a()
如果 tempfun() 需要访问任何变量,则可能需要将它们作为参数输入添加到函数中。我必须将所有可能的变量添加到函数中,并让它使用 temp_text 中调用的变量。这很尴尬。我使用的解决方案是允许配置文件中的值是一个字典,它指定数据的位置,也是一个字符串值,确定数据应该如何处理(函数读取的关键字)作为所有的键在模块中而不是在配置中处理数据。谢谢您的帮助!
推荐阅读
- yocto - 如何在 yocto 中指定较旧的 gcc 版本
- c# - 在 C# 中为多个测试类扩展报告不起作用?
- machine-learning - 如何使用 resnet 获得该预测的预测和置信度
- c++ - 在 Yocto Linux 中使用 Opencv 的 Gstreamer
- css - 使用波浪号将选择相邻的 div,但如果我使用类名而不是它不会..我错过了什么吗?
- python - 如何将 matplotlib.patches.FancyArrowPatch 的尾部宽度设置为零?
- ios - 在更新委托中创建 SKShapeNode 是否可以接受?
- azure-pipelines - 在 azure 管道 yaml 中的模板作业之间传递值
- android - Toast 出现在错误的时间
- python-3.x - 在Sqlite3,Python3中从数据库中的表中选择日期