exec('print(5)') # prints 5.
# exec 'print 5' if you use Python 2.x, nor the exec neither the print is a function there
exec('print(5)\nprint(6)') # prints 5{newline}6.
exec('if True: print(6)') # prints 6.
exec('5') # does nothing and returns nothing.
eval是一个内置函数(not语句),它计算表达式并返回表达式生成的值。示例:
x = eval('5') # x <- 5
x = eval('%d + 6' % x) # x <- 11
x = eval('abs(%d)' % -100) # x <- 100
x = eval('x = 5') # INVALID; assignment is not an expression.
x = eval('if 1: x = 4') # INVALID; if is a statement, not an expression.
>>> a = 5
>>> eval('37 + a') # it is an expression
42
>>> exec('37 + a') # it is an expression statement; value is ignored (None is returned)
>>> exec('a = 47') # modify a global variable as a side effect
>>> a
47
>>> eval('a = 47') # you cannot evaluate a statement
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
a = 47
^
SyntaxError: invalid syntax
>>> compile('for i in range(3): print(i)', '<string>', 'eval')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
for i in range(3): print(i)
^
SyntaxError: invalid syntax
>>> compile('for i in range(3): print(i)', '<string>'. 'eval')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
for i in range(3): print(i)
^
SyntaxError: invalid syntax
>>> exec('for i in range(3): print(i)')
0
1
2
>>> eval('for i in range(3): print(i)')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
for i in range(3): print(i)
^
SyntaxError: invalid syntax
>>> exec(compile('a = 5\na = 6', '<string>', 'single'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
a = 5
^
SyntaxError: multiple statements found while compiling a single statement
>>> eval('for i in range(3): print("Python is cool")')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
for i in range(3): print("Python is cool")
^
SyntaxError: invalid syntax
The first expression may also be a tuple of length 2 or 3. In this case, the optional parts must be omitted. The form exec(expr, globals) is equivalent to exec expr in globals, while the form exec(expr, globals, locals) is equivalent to exec expr in globals, locals. The tuple form of exec provides compatibility with Python 3, where exec is a function rather than a statement.
Python 2.7.11+ (default, Apr 17 2016, 14:00:29)
[GCC 5.3.1 20160413] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = exec('print(42)')
File "<stdin>", line 1
a = exec('print(42)')
^
SyntaxError: invalid syntax
exec是for语句,不返回任何内容。 eval用于表达式并返回表达式的值。
表达意味着“某事”,而陈述意味着“做某事”。
exec
不是表达式:Python2.x中的语句和Python3.x中的函数。它编译并立即计算字符串中包含的语句或语句集。示例:eval
是一个内置函数(not语句),它计算表达式并返回表达式生成的值。示例:compile
是exec
和eval
的低级版本。它不执行或计算语句或表达式,而是返回一个可以执行它的代码对象。模式如下:compile(string, '', 'eval')
返回如果完成eval(string)
本应执行的代码对象。注意,在此模式下不能使用语句;只有(单个)表达式有效。compile(string, '', 'exec')
返回如果完成exec(string)
本应执行的代码对象。这里可以使用任意数量的语句。compile(string, '', 'single')
与exec
模式类似,但它将忽略除第一条语句之外的所有内容。请注意,if
/else
语句及其结果被视为单个语句。简短的回答,或TL;DR
基本上,^{} 用于评估一个动态生成的Python表达式,而^{} 用于执行动态生成的Python代码,只是因为其副作用。
eval
和exec
有以下两个区别:eval
只接受单个表达式,exec
可以接受具有Python语句的代码块:循环、try: except:
、class
和函数/方法def
初始化等等。Python中的表达式可以作为变量赋值中的值:
eval
返回给定表达式的值,而exec
忽略其代码中的返回值,并始终返回None
(在Python 2中,它是一个语句,不能用作表达式,因此它实际上不返回任何内容)。在1.0-2.7版本中,
exec
是一个语句,因为CPython需要为函数生成一种不同类型的代码对象,这些函数使用exec
作为函数内部的副作用。在Python 3中,
exec
是一个函数;它的使用对使用它的函数的编译字节码没有影响。因此基本上:
在
'exec'
模式下,compile
将任意数量的语句编译成一个字节码,该字节码总是隐式返回None
,而在'eval'
模式下,它将一个单表达式编译成字节码,该字节码返回该表达式的值。在
'eval'
模式下(如果传入字符串,则使用eval
函数),如果源代码包含语句或除单个表达式之外的任何其他内容,则compile
将引发异常:实际上,语句“eval只接受一个表达式”仅在字符串(包含Python源代码)传递给} 编译成字节码,这就是区别真正的来源。
eval
时应用。然后在内部使用^{如果
code
对象(包含Python字节码)被传递给exec
或eval
,它们的行为完全相同,除了exec
忽略返回值,仍然始终返回None
。因此,可以使用eval
来执行具有语句的内容,如果您只是在compile
之前将其转换为字节码,而不是将其作为字符串传递:即使编译后的代码包含语句,也可以正常工作。它仍然返回
None
,因为这是从compile
返回的代码对象的返回值。在
'eval'
模式下(如果传入字符串,则使用eval
函数),如果源代码包含语句或除单个表达式之外的任何其他内容,则compile
将引发异常:答案越长,也就是血淋淋的细节
exec
和eval
^{} 函数(以前是a statement in Python 2)用于执行动态创建的语句或程序:
^{} 函数对single expression、和执行相同的操作,返回表达式的值:
exec
和eval
都接受程序/表达式作为包含源代码的str
、unicode
或bytes
对象运行,或者作为包含Python字节码的code
对象运行。如果包含源代码的
str
/unicode
/bytes
被传递给exec
,则其行为等效于:并且
eval
的行为类似于:由于所有表达式都可以用作Python中的语句(在Python中称为
Expr
节点;反之亦然),因此如果不需要返回值,则始终可以使用exec
。也就是说,可以使用eval('my_func(42)')
或exec('my_func(42)')
,区别在于eval
返回值由my_func
返回,并exec
丢弃它:其中,只有
exec
接受包含语句的源代码,如def
、for
、while
、import
,或class
、赋值语句(即a = 42
)或整个程序:exec
和eval
都接受另外两个位置参数-globals
和locals
-这是代码看到的全局和局部变量作用域。这些默认值为globals()
和locals()
在调用exec
或eval
的作用域内,但是任何字典都可以用于globals
,任何mapping
都可以用于locals
(当然包括dict
)。它们不仅可以用于限制/修改代码看到的变量,而且通常还用于捕获由exec
元代码创建的变量:(如果显示整个
g
的值,则会更长,因为exec
和eval
如果缺少内置模块,则会自动将其作为__builtins__
添加到全局中)。在Python 2中,
exec
语句的正式语法实际上是exec code in globals, locals
,如然而,替代语法
exec(code, globals, locals)
也一直被接受(见下文)。compile
内置的^{} 可以通过预先将源代码编译成
code
对象来加速对同一代码的重复调用。mode
参数控制compile
函数接受的代码片段的类型及其生成的字节码的类型。选择是'eval'
、'exec'
和'single'
:'eval'
模式需要一个表达式,并将生成字节码,在运行时将返回该表达式的值:'exec'
接受从单个表达式到整个代码模块的任何类型的python构造,并像执行模块顶级语句一样执行它们。代码对象返回None
:'single'
是'exec'
的一种有限形式,它接受包含单个语句(或由;
分隔的多个语句)的源代码。如果最后一个语句是表达式语句,则生成的字节码还将该表达式的值的repr
打印到标准输出(!)。一个
if
-elif
-else
链、一个带else
的循环以及带except
、else
和finally
的try
块被认为是一个语句。包含两个顶级语句的源片段对于
'single'
来说是一个错误,但在Python 2中有一个bug有时允许代码中有多个顶级语句;只编译第一个;其余的都被忽略:在Python2.7.8中:
在Python3.4.2中:
这对于制作交互式Python shell非常有用。但是,表达式的值是而不是返回,即使结果代码是
eval
。因此
exec
和eval
的最大区别实际上来自compile
函数及其模式。除了将源代码编译为字节码之外,
compile
还支持将abstract syntax trees(Python代码的解析树)编译为code
对象;将源代码编译为抽象语法树(用Python编写的ast.parse
只调用compile(source, filename, mode, PyCF_ONLY_AST)
);这些都用于动态修改源代码,对于动态代码创建,在复杂的情况下,通常更容易将代码作为节点树而不是文本行来处理。虽然
eval
只允许您计算包含单个表达式的字符串,但您可以eval
整个语句,甚至是已经compile
d成字节码的整个模块;也就是说,对于Python 2,print
是一个语句,不能直接由eval
引导:compile
它带有'exec'
mode进入一个code
对象,您可以将其;函数eval
将返回None
。如果查看CPython 3中的^{} 和^{} 源代码,这一点非常明显;它们都使用相同的参数调用} explicitly returns ^{} 。
PyEval_EvalCode
,唯一的区别是^{Python 2和Python 3之间
exec
的语法差异Python中的一个主要区别是
exec
是一个语句,而eval
是一个内置函数(两者都是Python 3中的内置函数)。 众所周知,Python 2中exec
的官方语法是exec code [in globals[, locals]]
。与大多数Python 2-to-3portingguidesseemto suggest不同,cpython2中的
exec
语句也可以使用与Python 3中的exec
函数调用完全类似的语法。原因是Python 0.9.9具有内置的exec(code, globals, locals)
函数!这个内置函数被exec
语句somewhere before Python 1.0 release替换。由于不需要破坏与Python 0.9.9、Guido van Rossum added a compatibility hack in 1993的向后兼容性:如果
code
是长度为2或3的元组,并且globals
和locals
没有传入exec
语句,那么code
将被解释为元组的第2和第3个元素分别是globals
和locals
。即使在Python 1.4 documentation (the earliest available version online)中也没有提到兼容性黑客;因此,许多移植指南和工具的作者都不知道它,直到它再次被documented使用为止:是的,在CPython 2.7中,它被简单地称为前向兼容选项(为什么人们会对后向兼容选项感到困惑), 当它实际上已经存在了20年的向后兼容性时。
因此,虽然
exec
是Python 1和Python 2中的语句,是Python 3和Python 0.9.9中的内置函数可能在所有广泛发布的Python版本中都有相同的行为;在Jython 2.5.2、pypy2.3.1(python2.7.6)和ironpython2.6.1中也有同样的行为(对他们来说,紧跟着CPython的非法行为是值得称赞的)。
在Pythons 1.0-2.7中,不能用它的兼容性技巧将
exec
的返回值存储到一个变量中:(这在Python 3中也没有用处,因为
exec
总是返回None
),或者传递对exec
的引用:哪一种模式是某人可能实际使用过的,尽管不太可能
或者在列表理解中使用它:
这是滥用列表理解(改用
for
循环!)。相关问题 更多 >
编程相关推荐