您如何将通过其他地方定义的函数和变量构建的表达式传递给exec()或eval()?

问题描述 投票:0回答:1

我有一个项目,需要在多个位置进行部署。要求代码在每个位置都相同,并且在配置文件中定义了自定义。大多数配置文件将是整数的字典,但在某些情况下,表达式将包含代码中定义的函数。我正在使用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

另一种尝试是尝试在本地字典中检索该函数:

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)

其中tempfun被修改为接受变量,但是我遇到了同样的问题。有没有办法用exec或eval以字符串形式读取一行代码,并且该字符串中的文本引用了在其他地方定义的变量和函数?我还要提到的是,代码将仅在合格的工程师处在计算机上本地运行,因此,与eval()有关的安全问题很少。谢谢

python scope exec eval global
1个回答
0
投票

我同意配置文件中的允许代码很尴尬,应该进行更改,但是我想指出问题的解决方案已经实现,以防其他人有相同的问题。解决方案是将代码嵌入到问题中所述的函数中:

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中调用的任何变量。这很尴尬。相反,我使用的解决方案是允许配置文件中的值成为字典,该字典指定数据的位置,并且还提供一个字符串值,该字符串值确定应如何处理数据(由函数读取的关键字)作为所有键的键在模块而不是配置中处理数据。感谢您的帮助!

© www.soinside.com 2019 - 2024. All rights reserved.