mag*_*gu_ 8 python matlab eval
我知道不应该使用eval
.出于所有明显的原因(性能,可维护性等).我的问题更侧重 - 是否有合法用途?应该使用它而不是以另一种方式实现代码.
由于它以多种语言实现并且可能导致糟糕的编程风格,因此我认为它仍然可用.
我发现合理使用的一个地方eval
是获取我的软件的使用者需要能够作为参数文件的一部分提供的小代码谓词。
例如,可能有一个名为“Data”的项目,它具有用于读取和写入数据的位置,但还需要在加载时对其应用一些谓词。在 Yaml 文件中,这可能如下所示:
Data:
Name: CustomerID
ReadLoc: some_server.some_table
WriteLoc: write_server.write_table
Predicate: "lambda x: x[:4]"
Run Code Online (Sandbox Code Playgroud)
从 Yaml 加载和解析对象后,我可以eval
将谓词字符串转换为可调用的 lambda 函数。在本例中,这意味着 CustomerID 是一个长字符串,在此特定实例中仅需要前 4 个字符。
Yaml 提供了一些笨拙的方法来神奇地调用对象构造函数(例如,使用类似于!Data
我上面的代码中的内容,然后Data
在代码中定义一个类,适当地使用 Yaml 挂钩到构造函数中)。事实上,我对 Yaml 魔法对象构造最大的批评之一是它实际上就像将整个参数文件变成一个巨大的eval
语句。如果您需要验证事物并且需要灵活地让代码的多个部分吸收参数文件的多个部分,那么这是非常有问题的。它也不太适合使用 Mako 进行模板化,而我上面的方法使这变得容易。
我认为这种可以使用任何 XML 工具轻松解析的更简单的设计更好,并且使用eval
允许用户传递他们想要的任何任意可调用对象。
关于为什么这在我的案例中有效的几点说明:
代码的用户不是 Python 程序员。他们没有能力编写自己的函数,然后只传递模块位置、函数名称和参数签名(尽管将所有这些放入参数文件中是解决此问题的另一种方法,该方法不依赖于eval
是否可以信任消费者编写代码。)
用户应对他们错误的 lambda 函数负责。我可以对eval
传递的谓词进行一些验证,甚至可以动态创建一些测试或有一个很好的失败模式,但在一天结束时,我可以告诉他们,提供有效的谓词是他们的工作,并且确保可以使用简单的谓词来操作数据。如果这个限制没有到位,我就必须为不同的系统去掉这个限制。
这些参数文件的用户组成了一个大多愿意遵守约定的小团体。如果事实并非如此,那么人们就会劫持谓词字段来做许多不适当的事情,这将是有风险的——而且这将很难防范。对于大型项目来说,这不是一个好主意。
我不知道我的观点是否普遍适用,但我想说,eval
如果您可以保证您的用户是一小群约定的维护者,那么使用为参数文件添加灵活性是很好的(我知道这是一个罕见的壮举)。