为什么"eval"不能在Python类函数中工作



假设我有一个python类,其属性为Pandas数据帧df。我想通过释放一个或多个预定义的查询来查询df,使用一个类函数,其中提供了一个或更多的查询句柄作为参数:

import pandas as pd
import numpy as np
class doorn:
def __init__(self):
self.name = 'foo'
self.df = pd.DataFrame(data={'A':np.arange(0, 10), 'B':np.arange(5, 15), 'C':np.arange(14, 24)}, index=[x for x in range(0, 10)])
def query_df(self, *query):
# query arguments must by formatted as 'q1', 'q2' etc
queries = [q for q in query]
q1 = self.df.loc[self.df.A > 2].index
q2 = self.df.loc[self.df.B < 13].index
q3 = self.df.loc[self.df.C > 15].index
sel_rows = set().union(*[eval(x, globals(), locals()) for x in queries])
self.df = self.df.loc[sel_rows]

现在,eval似乎找不到它所提供的查询字符串的实例:

>>> foo = doorn()
>>> foo.query_df('q1', 'q2')
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 17, in query_df
File "<input>", line 17, in <listcomp>
File "<string>", line 1, in <module>
NameError: name 'q1' is not defined

我的猜测是q1q2q3不存在于行理解命名空间中。或者其他什么,因为我还没有真正了解命名空间。正如文档中所建议的,我尝试通过提供globals()locals()作为eval的附加参数来解决这个问题,但没有成功。

我该如何解决这个问题?我甚至可以完全不使用eval吗?

我认为这是因为理解循环中的locals()与函数中的不相同,因此它们不包含'q1'。您可以使用全局变量,但我不建议这样做。此外,使用可能来自用户输入的eval可能是危险的,因为它可能会执行恶意代码。

我建议您将预定义查询的列表存储在字典中,如本例所示:

class doorn:
def __init__(self):
self.name = 'foo'
self.df = pd.DataFrame(data={'A':np.arange(0, 10), 'B':np.arange(5, 15), 'C':np.arange(14, 24)}, index=[x for x in range(0, 10)])
def query_df(self, *query):
# query arguments must by formatted as 'q1', 'q2' etc
queries = [q for q in query]
possible_queries = {'q1' : self.df.loc[self.df.A > 2].index,
'q2' : self.df.loc[self.df.B < 13].index,
'q3' : self.df.loc[self.df.C > 15].index}
sel_rows = set().union(*[possible_queries[x] for x in queries])
self.df = self.df.loc[sel_rows]

希望这对你有帮助。

相关内容

  • 没有找到相关文章

最新更新