3

我有许多处理大文件的python代码。在其中一些中,我在列之间执行操作或根据它们的内容进行选择。由于输入文件可以具有不同的结构,因此操作是通过命令行提供的,其语法类似于c3 + c5 -1(c3<4) & (c5>4)(或组合)。c4被解释为输入文件的第四列

我的文件看起来像这样('input_file.txt'):

21.3   4321.34   34.12   4   343.3  2  324
34.34  67.56     764.45  2   54.768 6  45265
986.96 87.98     234.09  1   54.456 3  5262
[...]

假设我想将第 4 列与第 5 列相加并减去 1。
我会这样做

import re
import numpy as np

operation = "c3 + c5 -1"  #in reality given from command line
pattern = re.compile(r"c(\d+?)") # compile the regex that matches the column number
# get the actual expression to evaluate
to_evaluate = pattern.sub("ifile[:,\\1]", operation) 
#to_evaluate is: "ifile[:,3] + ifile[:,5] -1"

ifile = np.loadtxt('input_file.txt')
result = eval(to_evaluate)  #evaluate the operation required
print(result)
# do the rest

输出

[5, 7, 3, ...]

我想出了这个实现,因为:

  1. numpy如果我想改变读取文件的方法(目前我可以决定使用or pandas)或者如果我想添加操作,它很容易编写和修改
  2. 在我能做的事情上给了我很大的自由。我可以治疗c3 + c5 -1(c3<4) & (c5>4)(c2+c4)>0以同样的方式。
  3. 我在所有代码中都有相同的签名:出错的可能性较小

我知道这eval可能是不安全的(尽管目前我是这些代码的唯一用户)并且可能比相应的代码慢,但我想不出更好的方法。

有没有人知道更好/更安全的方法来实施此类操作?

额外编辑:如果重要的话,我正在运行 python 2.7

4

1 回答 1

2

您可以进行更安全的评估

def safe_eval(eval_str, variable_dict = None):
    '''welll... mostly safe:
        http://lybniz2.sourceforge.net/safeeval.html
    '''
    if variable_dict == None:
        variable_dict = {}
    return eval(eval_str, {"__builtins__" : None}, variable_dict)

尽管它永远不会让非常了解 python 的人完全安全(参见http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html示例)

你的申请让我很困惑,所以我不确定我还能帮助你多少!


我不确定这是否有助于解决您正在做的事情,但是您可以做的一件事是将模块中的所有函数编译到字典中。

因此,您可以通过以下方式编译要使用的函数:

module_dict = {}
for n in dir(module):
 module_dict[n] = eval('module.'+n)

(我相信这个功能在 python 3 中是标准的。即所有模块模块字典都可以访问。)这将所有函数调用都放在字典形式中,从而加快调用速度。它还解决了评估安全问题。

如果您尝试使用 '+' 或 '=' 之类的操作,则可以从 object 获取它们的函数调用。添加和对象。当量_ 您可以将这些调用存储到您的字符串语法中。

不确定这是否有帮助。

于 2013-03-15T17:12:26.463 回答