Python 中 eval 的使用

发布于 2024-07-26 03:42:53 字数 74 浏览 4 评论 0原文

我在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

善良天后 2024-08-02 03:42:54

我刚刚发现了 eval 的一个很好的用法。 我正在为一些代码编写测试套件,并创建一个测试类,其中每个方法都是要运行的测试。 我想要一种方法,以便我可以运行所有测试方法,而不必单独调用每个方法。 所以,我写了一些相当肮脏的东西。

class Test:
    def __init__(self, *args):
       #bs

    def test1(self):
       #bs

    def test2(self):
       #bs

if __name__ == "__main__":
    import argparse
    #argparse bs
    test = Test(*bs_args)
    for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
        print(eval('test.{func}()'.format(func = func)))

任意测试用例的动态评估非常酷。 我只需要编写该方法,保存后我可以将该方法包含在我的测试套件中。 至于代码,我基本上只是检查测试对象中定义的方法,并确保它们不是测试对象的默认 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.

class Test:
    def __init__(self, *args):
       #bs

    def test1(self):
       #bs

    def test2(self):
       #bs

if __name__ == "__main__":
    import argparse
    #argparse bs
    test = Test(*bs_args)
    for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
        print(eval('test.{func}()'.format(func = func)))

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.

千笙结 2024-08-02 03:42:54

我用它向主程序输入变量值:

test.py var1=2 var2=True

...

var1=0
var2=False
for arg in sys.argv[1:]:
    exec(arg)

在主程序中允许关键字参数的粗略方法。 如果有更好的方法请告诉我!

I used it to input variable values to the main program:

test.py var1=2 var2=True

...

var1=0
var2=False
for arg in sys.argv[1:]:
    exec(arg)

A crude way to allow keyword args in the main program. If there's a better way let me know!

兮子 2024-08-02 03:42:54

我曾经遇到过将 eval 与 informix 数据库结合使用的情况。 由于某种原因,查询返回了一个像这样形成的字符串,

query_result = "['1', '2', '3']"

我只是在查询结果上使用了 eval,所以 python 将其解释为字符串列表。

[int(i) for i in eval(query_result)]
> [1,2,3]

我无法更改数据库,因此这是获取整数的快速(且肮脏)的方法。

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

query_result = "['1', '2', '3']"

I just used eval on the query result so python interpreted it as a list of strings.

[int(i) for i in eval(query_result)]
> [1,2,3]

I could not change the db so this was a quick (and dirty) way to get the integers.

歌入人心 2024-08-02 03:42:54

我使用 exec 在 Python 中创建一个插件系统。

    try:
        exec ("from " + plugin_name + " import Plugin")
        myplugin = Plugin(module_options, config=config)
    except ImportError, message:
        fatal ("No such module " + plugin_name + \
               " (or no Plugin constructor) in my Python path: " + str(message))
    except Exception:
        fatal ("Module " + plugin_name + " cannot be loaded: " + \
               str(sys.exc_type) + ": " + str(sys.exc_value) + \
               ".\n    May be a missing or erroneous option?")

有了这样的插件:

class Plugin:

    def __init__ (self):
        pass

    def query(self, arg):
         ...

你将能够这样调用它:

    result = myplugin.query("something")

我不认为你可以在没有 exec/eval 的情况下在 Python 中使用插件。

I use exec to create a system of plugins in Python.

    try:
        exec ("from " + plugin_name + " import Plugin")
        myplugin = Plugin(module_options, config=config)
    except ImportError, message:
        fatal ("No such module " + plugin_name + \
               " (or no Plugin constructor) in my Python path: " + str(message))
    except Exception:
        fatal ("Module " + plugin_name + " cannot be loaded: " + \
               str(sys.exc_type) + ": " + str(sys.exc_value) + \
               ".\n    May be a missing or erroneous option?")

With a plugin like:

class Plugin:

    def __init__ (self):
        pass

    def query(self, arg):
         ...

You will be able to call it like:

    result = myplugin.query("something")

I do not think you can have plugins in Python without exec/eval.

糖果控 2024-08-02 03:42:53

evalexec 是动态获取一些源代码的方便快捷的方法,也许稍微修改一下,然后执行它 - 但它们几乎从来没有最好的方法,特别是在生产代码中,而不是“快速而肮脏”的原型&c。

例如,如果我必须处理此类动态 Python 源,我会使用 ast 模块 - ast.literal_evaleval 安全得多(如果它是一个,你可以直接在表达式的字符串形式上调用它 -关闭并仅依赖于简单常量,或者首先执行 node = ast.parse(source) ,然后保留 node ,也许用合适的访问者来处理它,例如用于变量查找,然后是 literal_eval 节点)——或者,一旦将节点设置为正确的形状并审查了它的安全问题,我就可以编译它(生成一个代码对象)并从中构建一个新的函数对象。 远没有那么简单(除了对于最简单的情况,ast.literal_evaleval 一样简单!),但在生产质量代码中更安全、更可取。

对于许多任务,我看到人们(ab-)使用 execeval 来执行 Python 强大的内置函数,例如 getattr 和 < code>setattr、索引到globals()、&c,提供了更好且实际上通常更简单的解决方案。 对于解析 JSON 等特定用途,诸如 json 之类的库模块更好(例如,请参阅 SilentGhost 对耳鸣对此问题的回答的评论)。 等等等等...

eval and exec 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 than eval (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 do node = ast.parse(source) first, then keep the node around, perhaps munge it with suitable visitors e.g. for variable lookup, then literal_eval the node) -- or, once having put the node in proper shape and vetted it for security issues, I could compile it (yielding a code object) and build a new function object out of that. Far less simple (except that ast.literal_eval is just as simple as eval for the simplest cases!) but safer and preferable in production-quality code.

For many tasks I've seen people (ab-)use exec and eval for, Python's powerful built-ins, such as getattr and setattr, indexing into globals(), &c, provide preferable and in fact often simpler solutions. For specific uses such as parsing JSON, library modules such as json are better (e.g. see SilentGhost's comment on tinnitus' answer to this very question). Etc, etc...

月寒剑心 2024-08-02 03:42:53

关于 eval 的维基百科文章内容非常丰富,详细介绍了各种用途。

它建议的一些用途是:

  • 评估数学表达式
  • 编译器引导
  • 脚本(动态语言一般都非常适合这个)
  • 语言导师

The Wikipedia article on eval is pretty informative, and details various uses.

Some of the uses it suggests are:

  • Evaluating mathematical expressions
  • Compiler bootstrapping
  • Scripting (dynamic languages in general are very suitable to this)
  • Language tutors
人心善变 2024-08-02 03:42:53

您可能希望使用它来允许用户输入自己的“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.

染年凉城似染瑾 2024-08-02 03:42:53

过去我曾使用 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.

橘和柠 2024-08-02 03:42:53

在我曾经编写的一个程序中,您有一个输入文件,您可以在其中将几何参数指定为值和先前值的Python表达式,例如:

a = 10.0
b = 5.0
c = math.log10(a/b)

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 = 10.0
b = 5.0
c = math.log10(a/b)

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.

倦话 2024-08-02 03:42:53

我用它作为快速 JSON 解析器...

r='''
{
    "glossary": {
        "title": "example glossary"
        }
}
'''

print eval(r)['glossary']['title']

I use it as a quick JSON parser ...

r='''
{
    "glossary": {
        "title": "example glossary"
        }
}
'''

print eval(r)['glossary']['title']
极致的悲 2024-08-02 03:42:53

您可以在装饰器中使用 eval:

#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
    print("The number is %i", i)

#call
printNumber()

的复杂表达式

@lambda fun: lambda: fun(10)
def ...

虽然您不能使用像Nor 这样

@(lambda fun: lambda: fun(10))
def ...

,但您不能在那里使用 lambda 表达式,因为装饰器应该是标识符:

@myModule.functionWithOneArg

或函数调用:

@functionReturningFunctionWithOneArg(any, "args")

您会看到函数 eval 的调用带有字符串在这里有有效的语法,但 lambda 表达式没有。 (-> https://docs.python.org/3/参考/compound_stmts.html#function-definitions

You can use eval in a decorator:

#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
    print("The number is %i", i)

#call
printNumber()

while you cannot use complex expressions like

@lambda fun: lambda: fun(10)
def ...

nor

@(lambda fun: lambda: fun(10))
def ...

You cannot use a lambda-expression there, because the decorator should either be an identifier:

@myModule.functionWithOneArg

or a function call:

@functionReturningFunctionWithOneArg(any, "args")

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)

云醉月微眠 2024-08-02 03:42:53

eval() 通常不是很有用。 我用它做的少数事情之一(实际上是 exec(),但非常相似)是允许用户编写我用 Python 编写的应用程序的脚本。 如果它是用 C++ 之类的东西编写的,我就必须在应用程序中嵌入一个 Python 解释器。

eval() is not normally very useful. One of the few things I have used it for (well, it was exec() 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.

手长情犹 2024-08-02 03:42:53

Eval 是一种在程序内与 Python 解释器交互的方法。 您可以将文字传递给 eval ,它将它们作为 python 表达式进行计算。

例如 -

print eval("__import__('os').getcwd()")

将返回当前工作目录。

干杯

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 -

print eval("__import__('os').getcwd()")

would return the current working directory.

cheers

清旖 2024-08-02 03:42:53

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文