在Python、MATLAB等中使用eval

在Python、MATLAB等中使用eval,python,matlab,eval,Python,Matlab,Eval,我知道一个人不应该使用eval。由于所有明显的原因(性能、可维护性等)。我的问题更多的是站在一边——它有合法的用途吗?应该使用它,而不是以另一种方式实现代码 由于它是用几种语言实现的,可能会导致糟糕的编程风格,因此我认为它仍然可用是有原因的。我发现合理使用eval的一个地方是获取代码的小谓词,我的软件的使用者需要能够提供这些谓词作为参数文件的一部分 例如,可能有一个名为“Data”的项,它有一个读写数据的位置,但也需要在加载时对其应用一些谓词。在Yaml文件中,这可能如下所示: Data:

我知道一个人不应该使用
eval
。由于所有明显的原因(性能、可维护性等)。我的问题更多的是站在一边——它有合法的用途吗?应该使用它,而不是以另一种方式实现代码


由于它是用几种语言实现的,可能会导致糟糕的编程风格,因此我认为它仍然可用是有原因的。

我发现合理使用
eval
的一个地方是获取代码的小谓词,我的软件的使用者需要能够提供这些谓词作为参数文件的一部分

例如,可能有一个名为“Data”的项,它有一个读写数据的位置,但也需要在加载时对其应用一些谓词。在Yaml文件中,这可能如下所示:

Data:
    Name: CustomerID
    ReadLoc: some_server.some_table
    WriteLoc: write_server.write_table
    Predicate: "lambda x: x[:4]"
从Yaml加载和解析对象后,我可以使用
eval
将谓词字符串转换为可调用的lambda函数。在本例中,这意味着CustomerID是一个长字符串,在这个特定实例中只需要前4个字符

Yaml提供了一些笨拙的方法来神奇地调用对象构造函数(例如,在上面的代码中使用类似于
!Data
的东西,然后在代码中为
Data
定义了一个类,该类在构造函数中适当地使用Yaml钩子)。事实上,我对Yaml magic object构造的最大批评之一是,它实际上就像将整个参数文件变成一个巨大的
eval
语句。如果您需要验证一些东西,如果您需要代码的多个部分吸收参数文件的多个部分的方式的灵活性,那么这是非常有问题的。它也不容易与Mako一起模板化,而我上面的方法使它变得容易

我认为这种更简单的设计更好,可以用任何XML工具轻松解析,使用
eval
可以让用户传入他们想要的任意调用

在我的案例中,关于这一点为什么有效的几个注意事项:

  • 代码的用户不是Python程序员。他们没有能力编写自己的函数,然后只传递模块位置、函数名和参数签名(不过,将所有这些都放在参数文件中是另一种解决方法,如果可以信任消费者编写代码,则不依赖于
    eval

  • 用户应对其糟糕的lambda功能负责。我可以验证
    eval
    对传递的谓词是否有效,甚至可以动态创建一些测试,或者创建一个很好的失败模式,但在一天结束时,我可以告诉他们,他们的工作是提供有效的谓词,并确保数据可以用简单的谓词操作。如果这个约束不到位,我就不得不把它换成另一个系统

  • 这些参数文件的用户组成了一个小组,他们大多愿意遵守约定。如果这不是真的,那么人们会在谓词字段中插入许多不合适的内容,这将是很危险的——这将很难防范。在大型项目上,这不是一个好主意

  • 我不知道我的观点是否普遍适用,但我想说,如果你能保证你的用户是一小群传统拥护者,那么使用
    eval
    来增加参数文件的灵活性是很好的(我知道这是一项罕见的壮举)。

    首先,这里是


    您也可以聪明地在编译后的应用程序中使用
    eval()
    来构建mCode解释器,但Matlab编译器出于明显的原因不允许这样做。

    在Matlab中,当函数通过
    inputname
    函数使用输入参数的名称时,
    eval
    函数非常有用。例如,要重载内置的
    display
    函数(该函数对输入参数的名称敏感),需要使用
    eval
    函数。例如,要从重载的
    display
    调用内置的
    display
    ,可以执行以下操作

    function display(X)
        eval([inputname(1), ' = X;']);
        eval(['builtin(''display'', ', inputname(1), ');']);
    end
    
    在MATLAB中还有
    evalc
    。从文件中:

    T=EVAL(S)与EVAL(S)相同,只是 通常写入命令窗口,错误消息除外, 在字符数组T中捕获并返回(T中的行为 由“\n”个字符分隔)


    如果你仍然考虑这个代码<代码> EVA/COD>,那么在处理在命令窗口中显示有用信息的封闭源代码时,它是非常强大的,并且需要捕获和解析输出。< /P>好问题。我很想看看答案。@当然我不同意。这个问题问的不是“eval的合法用途是什么”,而是“eval的这种特定用途合法吗?”。因此,答案说这种用法不好,如何避免,但不是什么时候应该使用。为什么问题从“在Matlab中使用eval”改为“Python”?固定了标题。也许有人不喜欢Matlab。描述了Mathworks链接的几种用法。+1!这实际上是一种很好的思维方式。但我不确定这个计数是否正确,因为它不是那样工作的。