Python 中 eval 的使用
我在使用 Python 时偶然发现了一个 eval() 函数。 我想不出需要这个函数的情况,除了作为语法糖。 可以举个什么例子吗?
There is an eval()
function in Python I stumbled upon while playing around. I cannot think of a case when this function is needed, except maybe as syntactic sugar. What could an example be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
我刚刚发现了 eval 的一个很好的用法。 我正在为一些代码编写测试套件,并创建一个测试类,其中每个方法都是要运行的测试。 我想要一种方法,以便我可以运行所有测试方法,而不必单独调用每个方法。 所以,我写了一些相当肮脏的东西。
任意测试用例的动态评估非常酷。 我只需要编写该方法,保存后我可以将该方法包含在我的测试套件中。 至于代码,我基本上只是检查测试对象中定义的方法,并确保它们不是测试对象的默认 python“魔术”方法或属性。 之后我可以假设它们是方法并且可以进行评估。
I just came across a good use of eval. I was writing a test suite for some code, and created a Test class, where every method was a test to be run. I wanted a way so that I could run all the test methods without having to call each method individually. So, I wrote something rather dirty.
Dynamic evaluation of arbitrary test cases is pretty cool. I just have to write the method, and after saving I can include the method in my test suite. As for the code, I basically just inspect the methods defined in the test object, and make sure they aren't default python "magic" methods or attributes to the Test object. After that I can assume they are methods and can be evaluated.
我用它向主程序输入变量值:
test.py var1=2 var2=True
...
在主程序中允许关键字参数的粗略方法。 如果有更好的方法请告诉我!
I used it to input variable values to the main program:
test.py var1=2 var2=True
...
A crude way to allow keyword args in the main program. If there's a better way let me know!
我曾经遇到过将 eval 与 informix 数据库结合使用的情况。 由于某种原因,查询返回了一个像这样形成的字符串,
我只是在查询结果上使用了 eval,所以 python 将其解释为字符串列表。
我无法更改数据库,因此这是获取整数的快速(且肮脏)的方法。
I had a case where I used eval in combination with an informix database. For some reason the query returned a string formed like this
I just used eval on the query result so python interpreted it as a list of strings.
I could not change the db so this was a quick (and dirty) way to get the integers.
我使用 exec 在 Python 中创建一个插件系统。
有了这样的插件:
你将能够这样调用它:
我不认为你可以在没有
exec
/eval
的情况下在 Python 中使用插件。I use
exec
to create a system of plugins in Python.With a plugin like:
You will be able to call it like:
I do not think you can have plugins in Python without
exec
/eval
.eval
和exec
是动态获取一些源代码的方便快捷的方法,也许稍微修改一下,然后执行它 - 但它们几乎从来没有最好的方法,特别是在生产代码中,而不是“快速而肮脏”的原型&c。例如,如果我必须处理此类动态 Python 源,我会使用 ast 模块 -
ast.literal_eval
比eval
安全得多(如果它是一个,你可以直接在表达式的字符串形式上调用它 -关闭并仅依赖于简单常量,或者首先执行node = ast.parse(source)
,然后保留node
,也许用合适的访问者来处理它,例如用于变量查找,然后是literal_eval
节点)——或者,一旦将节点设置为正确的形状并审查了它的安全问题,我就可以编译
它(生成一个代码对象)并从中构建一个新的函数对象。 远没有那么简单(除了对于最简单的情况,ast.literal_eval
与eval
一样简单!),但在生产质量代码中更安全、更可取。对于许多任务,我看到人们(ab-)使用
exec
和eval
来执行 Python 强大的内置函数,例如getattr
和 < code>setattr、索引到globals()
、&c,提供了更好且实际上通常更简单的解决方案。 对于解析 JSON 等特定用途,诸如json
之类的库模块更好(例如,请参阅 SilentGhost 对耳鸣对此问题的回答的评论)。 等等等等...eval
andexec
are handy quick-and-dirty way to get some source code dynamically, maybe munge it a bit, and then execute it -- but they're hardly ever the best way, especially in production code as opposed to "quick-and-dirty" prototypes &c.For example, if I had to deal with such dynamic Python sources, I'd reach for the ast module --
ast.literal_eval
is MUCH safer thaneval
(you can call it directly on a string form of the expression, if it's a one-off and relies on simple constants only, or donode = ast.parse(source)
first, then keep thenode
around, perhaps munge it with suitable visitors e.g. for variable lookup, thenliteral_eval
the node) -- or, once having put the node in proper shape and vetted it for security issues, I couldcompile
it (yielding a code object) and build a new function object out of that. Far less simple (except thatast.literal_eval
is just as simple aseval
for the simplest cases!) but safer and preferable in production-quality code.For many tasks I've seen people (ab-)use
exec
andeval
for, Python's powerful built-ins, such asgetattr
andsetattr
, indexing intoglobals()
, &c, provide preferable and in fact often simpler solutions. For specific uses such as parsing JSON, library modules such asjson
are better (e.g. see SilentGhost's comment on tinnitus' answer to this very question). Etc, etc...关于
eval
的维基百科文章内容非常丰富,详细介绍了各种用途。它建议的一些用途是:
The Wikipedia article on
eval
is pretty informative, and details various uses.Some of the uses it suggests are:
您可能希望使用它来允许用户输入自己的“scriptlet”:小表达式(甚至是小函数),可用于自定义复杂的行为> 系统。
在这种情况下,如果您不必太关心安全隐患(例如您拥有受过教育的用户群),那么 eval() 可能是一个不错的选择。
You may want to use it to allow users to enter their own "scriptlets": small expressions (or even small functions), that can be used to customize the behavior of a complex system.
In that context, and if you do not have to care too much for the security implications (e.g. you have an educated userbase), then eval() may be a good choice.
过去我曾使用 eval() 向我的应用程序添加调试接口。 我创建了一个 telnet 服务,它将您带入正在运行的应用程序的环境中。 输入通过 eval() 运行,因此您可以在应用程序中交互式运行 Python 命令。
In the past I have used eval() to add a debugging interface to my application. I created a telnet service which dropped you into the environment of the running application. Inputs were run through eval() so you can interactively run Python commands in the application.
在我曾经编写的一个程序中,您有一个输入文件,您可以在其中将几何参数指定为值和先前值的Python表达式,例如:
Python解析器读取此输入文件并获得评估值和表达式的最终数据使用 eval()。
我并不认为这是一个很好的编程,但我不必驱动核反应堆。
In a program I once wrote, you had an input file where you could specify geometric parameters both as values and as python expressions of the previous values, e.g.:
A Python parser read this input file and obtained the final data evaluating the values and the expressions using eval().
I don't claim it to be good programming, but I did not have to drive a nuclear reactor.
我用它作为快速 JSON 解析器...
I use it as a quick JSON parser ...
您可以在装饰器中使用 eval:
的复杂表达式
虽然您不能使用像Nor 这样
,但您不能在那里使用 lambda 表达式,因为装饰器应该是标识符:
或函数调用:
您会看到函数 eval 的调用带有字符串在这里有有效的语法,但 lambda 表达式没有。 (-> https://docs.python.org/3/参考/compound_stmts.html#function-definitions)
You can use eval in a decorator:
while you cannot use complex expressions like
nor
You cannot use a lambda-expression there, because the decorator should either be an identifier:
or a function call:
You see that the call of the function eval with a string has valid syntax here, but the lambda-expression not. (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions)
eval()
通常不是很有用。 我用它做的少数事情之一(实际上是 exec(),但非常相似)是允许用户编写我用 Python 编写的应用程序的脚本。 如果它是用 C++ 之类的东西编写的,我就必须在应用程序中嵌入一个 Python 解释器。eval()
is not normally very useful. One of the few things I have used it for (well, it wasexec()
actually, but it's pretty similar) was allowing the user to script an application that I wrote in Python. If it were written in something like C++, I would have to embed a Python interpreter in the application.Eval 是一种在程序内与 Python 解释器交互的方法。 您可以将文字传递给 eval ,它将它们作为 python 表达式进行计算。
例如 -
将返回当前工作目录。
干杯
Eval is a way to interact with the Python interpreter from within a program. You can pass literals to eval and it evaluates them as python expressions.
For example -
would return the current working directory.
cheers
eval() 用于单个句子,而 exec() 用于多个句子。
通常我们使用它们来添加或访问一些脚本,就像 bash shell 一样。
因为它们可以在内存中运行一些字节脚本,如果您有一些重要的数据或脚本,您可以解码并解压缩您的“秘密”,然后做您想做的一切。
eval() is for single sentence, while exec() is for multiple ones.
usually we use them to add or visit some scripts just like bash shell.
because of they can run some byte scripts in the memory, if you have some important data or script you can decode and unzip your 'secret' then do everything you wanna.