Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用exec和eval_Python_Eval_Exec - Fatal编程技术网

在Python中使用exec和eval

在Python中使用exec和eval,python,eval,exec,Python,Eval,Exec,因此,我已经了解了exec和eval以及compile所做的事情。但是为什么我需要使用它们呢?我不清楚使用场景 谁能给我举几个例子,让我更好地理解这个概念。因为我知道这都是理论。你只是想举个例子吗?您可以编写一个简单的应用程序,从中读取标准,并允许用户输入各种表达式,如(4*2)/8-1。在其他语言(java、C++等)中,这几乎不可能进行评估,但是在Python中,它是简单的,只是: eval((4*2)/8 - 1) 也就是说,除非你小心,否则使用这些东西可能非常危险,因为它们(本质上)允

因此,我已经了解了
exec
eval
以及
compile
所做的事情。但是为什么我需要使用它们呢?我不清楚使用场景


谁能给我举几个例子,让我更好地理解这个概念。因为我知道这都是理论。你只是想举个例子吗?您可以编写一个简单的应用程序,从中读取标准,并允许用户输入各种表达式,如
(4*2)/8-1
。在其他语言(java、C++等)中,这几乎不可能进行评估,但是在Python中,它是简单的,只是:

eval((4*2)/8 - 1)

也就是说,除非你小心,否则使用这些东西可能非常危险,因为它们(本质上)允许用户进行大量访问。

这用于元编程(当程序自行编写时)。例如,您有不同种类的动物,它们被描述为不同的类别:狮子、老虎、马、驴。你想模拟它们之间的杂交,例如狮子和老虎之间的杂交。编写程序时,您无法确定用户将如何穿越动物,但可以动态创建新的动物类:

new_class_name = boy.class.to_str() + girl.class.to_str()
eval("class " + new_class_name + " extends " + boy.class.to_str() + ", " + girl.class.to_str())

对不起,我忘了一些。所以有一堆伪代码。

你不需要使用它们,我认为你应该避免使用它们

它们只在生成代码本身的情况下才有用,而最终很可能会被认为是错误的做法


如果您正在考虑将eval()用于数学表达式之类的内容,那么最好在计算输入之前对其进行清理。你永远不知道用户发送的哪种“文本”可能会破坏应用程序本身。

标准库提供了一个关于如何使用
exec
的指导性示例。使用它动态地构建类

template = '''class %(typename)s(tuple):
    '%(typename)s(%(argtxt)s)' \n
    __slots__ = () \n
    _fields = %(field_names)r \n
    def __new__(_cls, %(argtxt)s):
        'Create new instance of %(typename)s(%(argtxt)s)'
        return _tuple.__new__(_cls, (%(argtxt)s)) \n
    ...'''

   namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
                     OrderedDict=OrderedDict, _property=property, _tuple=tuple)
   try:
       exec template in namespace
   except SyntaxError, e:
       raise SyntaxError(e.message + ':\n' + template)

ast
使用
compile
从Python源代码生成抽象语法树。诸如
pyflakes
之类的模块使用它们来解析和验证Python

def parse(expr, filename='<unknown>', mode='exec'):
    """
    Parse an expression into an AST node.
    Equivalent to compile(expr, filename, mode, PyCF_ONLY_AST).
    """
    return compile(expr, filename, mode, PyCF_ONLY_AST)
def parse(expr,filename='',mode='exec'):
"""
将表达式解析为AST节点。
等效于编译(expr、文件名、模式、仅PyCF__AST)。
"""
返回编译(expr、文件名、模式、仅PyCF\u AST)

这是一个有效的用例。在python粘贴中间件(用于web编程)中,当引发异常时,它会在浏览器中创建一个命令行。这项工作可能会使用这样的方法。此外,在Blender中,有一个选项可以使用python表达式设置值的动画,这可以使用eval来实现。

我将给出一个示例,其中我使用了
eval
,我认为这是最佳选择

我正在写一个简单的软件测试实用程序。。。测试学生练习是否符合作业要求的东西。目标是提供一种简单的配置文件作为测试规范的方法(避免使用编程语言描述/记录/实现基本编程任务的测试用例的“鸡和蛋”问题)

我的工具基于标准库中的ConfigParser。但是,我确实希望能够表示任意Python字符串(包括\n、\t的插值,尤其是从中读取的值中的任何插值十六进制编码ASCII字符)

我的解决方案是围绕一个
parsed_string=eval(''%s''%cfg\u read_item)
进行
try
,然后是相同的三重双引号版本(''%s')

在这种情况下,另一种选择是编写(或找到一个预先编写的)Python语言解析器,并找出如何将其包含在我的程序中并使其适应我的程序(我不担心学生提交的代码会欺骗我的解析器,如果它被关起来,就会越狱,删除我所有的文件,把我的信用卡号码发送到罗马尼亚等等)*

*(部分原因是我在Linux下从一个不可信的无头用户帐户测试它们)


正如这里其他人所说的,还有其他用例,在这些用例中,您根据输入数据从模板构建代码,并且需要执行该代码(元编程)。您应该始终能够以另一种方式完成这些任务。但是,无论何时,只要这种替代方法需要编写接近编写通用编程语言解析器/编译器/解释器的编码工作……那么
eval
可能是更好的方法。

我认为我有一个有效的用法。我正在Blender 2.6.4中使用Python 3.2.1使用x、y坐标(在z平面中)修改一组点的步骤

目标是围绕每个现有点添加新点的同心环,这些同心环表现为涟漪(就像在池塘中扔石头一样)问题是我想让涟漪以建设性/破坏性的方式相互干扰,所以首先我要遍历并构建一个以每个点为中心的“涟漪方程”,将所有涟漪方程相加成一个巨大的数学方程,然后将原始点输入其中,以生成co更正z值以将每个值指定给


我的计划是将等式中的每个附加项作为字符串附加到上一个项,然后使用eval()计算新点集的z值。

事实:像
eval
这样的东西很少是一个有效的选择,而且只有在已知输入到它的字符串是安全的情况下。尝试在Python标准库中的Python源代码文件中搜索它们。如果您想看到基本的Python功能,这总是一个有趣的开始es使用得很好。
exec
eval
在中可能非常有用。不,这不是
eval
的有效用法——你应该使用
type
。让“元编程”等于“坏习惯”有点苛刻。元编程虽然有时更复杂、更容易出错,但会产生错误