在Python中使用eval?

时间:2009-07-06 14:23:08

标签: python dynamic eval

Python中有一个eval()函数我在玩游戏时偶然发现。我不能想到需要这个功能的情况,除了可能是语法糖。谁能举个例子?

14 个答案:

答案 0 :(得分:43)

evalexec是方便快捷的方式来动态获取一些源代码,可能会稍微麻烦一点,然后执行它 - 但它们几乎不是最好的方法,特别是在生产代码中,而不是“快速和肮脏”的原型& c。

例如,如果我不得不处理这样的动态Python源代码,那么我会找到ast模块 - ast.literal_evaleval更安全(你可以称之为直接在表达式的字符串形式上,如果它是一次性的并且仅依赖于简单的常量,或者首先执行node = ast.parse(source),那么保持node左右,或者将其与合适的访问者进行混合,例如对于变量查找,然后literal_eval节点) - 或者,一旦将节点置于适当的形状并审查它的安全问题,我可以compile它(产生一个代码对象)并构建一个新的函数对象出于那个。更简单(除了ast.literal_eval对于最简单的情况就像eval一样简单!)但在生产质量代码中更安全,更可取。

对于许多任务,我看到人们(ab-)使用execeval来使用Python强大的内置函数,例如getattrsetattr,编制索引进入globals(),& c,提供优选的,实际上通常更简单的解决方案。对于特定用途,例如解析JSON,诸如json之类的库模块更好(例如,请参阅SilentGhost关于tinnitus对此问题的回答的评论)。等等...

答案 1 :(得分:15)

Wikipedia article on eval非常有用,详细介绍了各种用途。

它建议的一些用途是:

答案 2 :(得分:13)

您可能希望使用它来允许用户输入自己的“scriptlet”:表达式(甚至小函数),可用于自定义复杂的行为系统。
在这种情况下,如果您不必过多关注安全隐患(例如,您拥有受过良好教育的用户群),那么eval()可能是一个不错的选择。

答案 3 :(得分:5)

过去我使用eval()为我的应用程序添加调试接口。我创建了一个telnet服务,它将您置于正在运行的应用程序的环境中。输入是通过eval()运行的,因此您可以在应用程序中以交互方式运行Python命令。

答案 4 :(得分:4)

在我曾写过的程序中,你有一个输入文件,你可以在其中指定几何参数作为值和以前值的python表达式,例如:

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

python解析器读取此输入文件并使用eval()获取评估值和表达式的最终数据。

我并不认为它是一个好的编程,但我没有必要驾驶核反应堆。

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

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

例如 -

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

将返回当前的工作目录。

欢呼声

答案 8 :(得分:1)

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

runascurrentuser

虽然你不能使用像

这样的复杂表达式
#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 ...

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

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

或函数调用:

@myModule.functionWithOneArg

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

答案 9 :(得分:0)

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

test.py var1 = 2 var2 = True

...

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

允许主程序中的关键字args的粗略方法。如果有更好的方式让我知道!

答案 10 :(得分:0)

eval()用于单句,而exec()用于多个句子。

通常我们使用它们来添加或访问一些脚本,就像bash shell一样。

因为他们可以在内存中运行一些字节脚本,如果你有一些重要的数据或脚本,你可以解密和解压缩你的秘密'然后做你想做的一切。

答案 11 :(得分:0)

我刚刚好好利用了eval。我正在为一些代码编写测试套件,并创建了一个Test类,其中每个方法都是一个要运行的测试。我想要一种方法,这样我就可以运行所有测试方法而无需单独调用每个方法。所以,我写了一些相当脏的东西。

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" magic" Test对象的方法或属性。之后,我可以假设它们是方法,可以进行评估。

答案 12 :(得分:0)

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

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

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

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

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

答案 13 :(得分:-1)

我使用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中使用插件。