Python中有一个eval()
函数我在玩游戏时偶然发现。我不能想到需要这个功能的情况,除了可能是语法糖。谁能举个例子?
答案 0 :(得分:43)
eval
和exec
是方便快捷的方式来动态获取一些源代码,可能会稍微麻烦一点,然后执行它 - 但它们几乎不是最好的方法,特别是在生产代码中,而不是“快速和肮脏”的原型& c。
例如,如果我不得不处理这样的动态Python源代码,那么我会找到ast模块 - ast.literal_eval
比eval
更安全(你可以称之为直接在表达式的字符串形式上,如果它是一次性的并且仅依赖于简单的常量,或者首先执行node = ast.parse(source)
,那么保持node
左右,或者将其与合适的访问者进行混合,例如对于变量查找,然后literal_eval
节点) - 或者,一旦将节点置于适当的形状并审查它的安全问题,我可以compile
它(产生一个代码对象)并构建一个新的函数对象出于那个。更简单(除了ast.literal_eval
对于最简单的情况就像eval
一样简单!)但在生产质量代码中更安全,更可取。
对于许多任务,我看到人们(ab-)使用exec
和eval
来使用Python强大的内置函数,例如getattr
和setattr
,编制索引进入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中使用插件。