Python 使用(out)eval()执行用户给定的操作

Python 使用(out)eval()执行用户给定的操作,python,eval,Python,Eval,我有很多python代码可以处理大文件。在其中一些操作中,我在列之间执行操作,或者根据其内容进行选择。由于输入文件可以具有不同的结构,因此操作通过命令行提供,语法如下c3+c5-1或(c34)(或组合)c4被解释为输入文件的第四列 我的文件如下所示(“input_file.txt”): 假设我想将第4列与第5列相加,然后减去1。 我愿意 import re import numpy as np operation = "c3 + c5 -1" #in reality given from c

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

我的文件如下所示(“input_file.txt”):

假设我想将第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,…]

我提出这个实现是因为:

  • 如果我想更改读取文件的方法(此时我可以决定使用
    numpy
    pandas
    ),或者如果我想添加操作,那么编写和修改都很容易
  • 在我能做的事情上给了我很大的自由。我可以用同样的方法处理
    c3+c5-1
    (c34)
    (c2+c4)>0
  • 我在所有代码中都有相同的签名:它不太可能出错
  • 我知道
    eval
    可能是不安全的(尽管目前我是这些代码的唯一用户),并且可能比相应的代码慢,但我想不出更好的方法

    是否有人知道实施此类操作的更好/更安全的方法


    额外编辑:如果有必要,我正在运行python 2.7,您可以进行更安全的评估

    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的人知道 (参见示例)

    你的申请让我很困惑,所以我不知道我还能帮你多少忙


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

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

    module_dict = {}
    for n in dir(module):
     module_dict[n] = eval('module.'+n)
    
    (我相信这个功能在Python3中是标准的。也就是说,所有的模块字典都可以访问。)这使得所有的函数调用都以字典的形式进行,从而加快了调用速度。它还解决了评估安全问题

    如果您试图使用像“+”或“=”这样的操作,您可以从object获取它们的函数调用。添加和object。eq。您可以将这些调用存储到字符串语法中


    不确定这是否有用。

    谢谢你的功能和链接,非常有趣。如果你能告诉我你发现什么让我困惑,我可以试着编辑这个问题,把它弄清楚。我只是不理解这些文件操作。隐马尔可夫模型。。。我有个主意。请稍后参阅上文。如果我添加几行模拟文件和我期望的答案,会有帮助吗?您可以做些什么来澄清您的问题,可能会帮助人们回答:)我(想我)在编辑中理解您的观点。我看到的主要问题是,如果使用括号,它可能会变得复杂。
    module_dict = {}
    for n in dir(module):
     module_dict[n] = eval('module.'+n)