题
有一个 eval()
我在玩的时候偶然发现了Python中的函数。我想不出需要这个函数的情况,除了作为语法糖。谁能举个例子吗?
解决方案
eval
和 exec
是动态获取一些源代码的方便而快速的方法,也许稍微修改一下,然后执行它 - 但它们几乎不是最好的方法,特别是在生产代码中,而不是“快速而肮脏” “原型等。
例如,如果我必须处理这样的动态 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 对耳鸣对此问题的回答的评论)。等等等等..
其他提示
您可能想用它来让用户输入自己的“脚本小程序”:小表达式(或者更小的功能),可以使用自定义的行为复杂强>系统。结果 在这种情况下,如果你也不必太在意了安全隐患(例如你有一个受过教育的用户群),然后的eval()可能是一个不错的选择。
在过去我已经使用的eval()到调试接口添加到我的申请。我创建了下降到你运行的应用程序的环境中的Telnet服务。输入是通过EVAL()运行,以便可以交互运行的Python在应用程序命令。
在一个程序我曾经写过,你有一个输入文件,其中可以指定几何参数既作为值和先前值的Python表达式,例如:
a=10.0
b=5.0
c=math.log10(a/b)
一个蟒解析器读取此输入文件和所获得的最终数据评价值和使用eval表达式()。
我不要求它是良好的编程,但我没有开车核反应堆。
我用它作为一个快速JSON解析器...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
eval()
通常不是非常有用的。有一个问题我已经用了几件事情(当然,它实际上exec()
,但它是非常相似)是允许用户脚本,我用Python写了一份申请。如果它被写在类似C ++,我必须嵌入在应用程序中Python解释。
评估是在程序中与Python解释进行交互的一种方式。可以传递文字给eval并评估它们作为Python表达式。
例如 -
print eval("__import__('os').getcwd()")
将返回当前工作目录。
欢呼声
可以在一个装饰使用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 ...
,也不
@(lambda fun: lambda: fun(10))
def ...
您不能使用λ-表达那里,因为装饰要么是一个标识符
@myModule.functionWithOneArg
或一个函数调用:
@functionReturningFunctionWithOneArg(any, "args")
您看到该函数的eval一个字符串调用具有有效的语法在这里,但在lambda表达式没有。 ( - > https://docs.python.org/3/reference /compound_stmts.html#function-definitions )
我它用于输入变量值到主程序:
test.py VAR1 = 2 VAR2 =真
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
一个粗的方式来允许在主程序关键字ARGS。如果有更好的方式让我知道!
的eval()是用于单句,而EXEC()是用于多者。
通常我们用它来添加或访问一些脚本就像bash shell的。
,因为它们可以在内存中运行一些字节的脚本,如果你有一些重要的数据或脚本可以解码和解压您的“秘密”,然后做一切你想做的。
我只是碰到一个良好的使用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的“神奇”的方法或属性的测试对象。之后,我可以假设它们是方法和进行评价。
我用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")
我不认为你可以有插件在Python没有exec
/ eval
。