为什么 "eval "在Python类函数中不起作用?

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

假设我有一个带有Pandas数据框架的Python类。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

我猜测是 q1, q2, q3 不存在于行理解命名空间中。或者别的什么,因为我还没有真正理解Namespaces。我曾试过通过提供 globals()locals() 作为附加参数的 eval正如《公约》所建议的那样 文件但没有成功。

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

python pandas namespaces eval nameerror
1个回答
2
投票

我想这是因为 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]

希望这能帮助你。

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