标签归档:exec

从PHP运行Python脚本

问题:从PHP运行Python脚本

我正在尝试使用以下命令从PHP运行Python脚本:

exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');

但是,PHP根本不会产生任何输出。错误报告设置为E_ALL,并且display_errors打开。

这是我尝试过的:

  • 我使用python2/usr/bin/python2python2.7不是/usr/bin/python2.7
  • 我还使用了相对路径而不是绝对路径,它也没有改变任何东西。
  • 我试着使用的命令execshell_execsystem

但是,如果我跑步

if (exec('echo TEST') == 'TEST')
{
    echo 'exec works!';
}

shutdown now什么也没做,却可以正常工作。

PHP有权访问和执行文件。

编辑:感谢亚历杭德罗,我能够解决此问题。如果您遇到相同的问题,请不要忘记您的Web服务器可能/希望不是以root用户身份运行。尝试以您的Web服务器用户或具有类似权限的用户身份登录,然后尝试自己运行命令。

I’m trying to run a Python script from PHP using the following command:

exec('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');

However, PHP simply doesn’t produce any output. Error reporting is set to E_ALL and display_errors is on.

Here’s what I’ve tried:

  • I used python2, /usr/bin/python2 and python2.7 instead of /usr/bin/python2.7
  • I also used a relative path instead of an absolute path which didn’t change anything either.
  • I tried using the commands exec, shell_exec, system.

However, if I run

if (exec('echo TEST') == 'TEST')
{
    echo 'exec works!';
}

it works perfectly fine while shutdown now doesn’t do anything.

PHP has the permissions to access and execute the file.

EDIT: Thanks to Alejandro, I was able to fix the problem. If you have the same problem, don’t forget that your webserver probably/hopefully doesn’t run as root. Try logging in as your webserver’s user or a user with similar permissions and try to run the commands yourself.


回答 0

在Ubuntu Server 10.04上测试。希望它对Arch Linux也有帮助。

在PHP中使用shell_exec函数

通过shell执行命令并以字符串形式返回完整的输出。

它从执行的命令返回输出,如果发生错误或命令不产生任何输出,则返回NULL。

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

在Python文件中test.py,在第一行中验证以下文本:(请参见shebang解释)

#!/usr/bin/env python

此外,Python文件必须具有正确的特权(如果PHP脚本在浏览器或curl中运行,则对用户www-data / apache的执行)和/或必须是“可执行的”。此外,所有进入.py文件的命令都必须具有正确的特权:

采取从PHP手册

对于那些试图在unix类型的平台上使用shell_exec并且似乎无法使其正常工作的人,请快速提醒一下。PHP以系统上的Web用户身份执行(对于Apache,通常为www),因此您需要确保Web用户对您在shell_exec命令中尝试使用的任何文件或目录具有权限。否则,它似乎什么也没做。

为了使在UNIX型平台上的可执行文件

chmod +x myscript.py

Tested on Ubuntu Server 10.04. I hope it helps you also on Arch Linux.

In PHP use shell_exec function:

Execute command via shell and return the complete output as a string.

It returns the output from the executed command or NULL if an error occurred or the command produces no output.

<?php 

$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;

?>

In Python file test.py, verify this text in first line: (see shebang explain):

#!/usr/bin/env python

Also Python file must have correct privileges (execution for user www-data / apache if PHP script runs in browser or curl) and/or must be “executable”. Also all commands into .py file must have correct privileges:

Taken from php manual:

Just a quick reminder for those trying to use shell_exec on a unix-type platform and can’t seem to get it to work. PHP executes as the web user on the system (generally www for Apache), so you need to make sure that the web user has rights to whatever files or directories that you are trying to use in the shell_exec command. Other wise, it won’t appear to be doing anything.

To make executable a file on unix-type platforms:

chmod +x myscript.py

回答 1

我建议passthru直接使用和处理输出缓冲区:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 

I recommend using passthru and handling the output buffer directly:

ob_start();
passthru('/usr/bin/python2.7 /srv/http/assets/py/switch.py arg1 arg2');
$output = ob_get_clean(); 

回答 2

如果您想知道命令的返回状态并获取整个stdout输出,则可以实际使用exec

$command = 'ls';
exec($command, $out, $status);

$out是所有行的数组。$status是退货状态。对于调试非常有用。

如果您还想查看stderr输出,则可以使用proc_open或直接将其添加2>&1到中$command。后者通常足以使事情正常运行,并更快地实现。

If you want to know the return status of the command and get the entire stdout output you can actually use exec:

$command = 'ls';
exec($command, $out, $status);

$out is an array of all lines. $status is the return status. Very useful for debugging.

If you also want to see the stderr output you can either play with proc_open or simply add 2>&1 to your $command. The latter is often sufficient to get things working and way faster to “implement”.


回答 3

亚历杭德罗(Alejandro)钉上了钉子,为异常(Ubuntu或Debian)添加了说明-我没有代表要添加到答案本身:

sudoers文件: sudo visudo

添加了异常: www-data ALL=(ALL) NOPASSWD: ALL

Alejandro nailed it, adding clarification to the exception (Ubuntu or Debian) – I don’t have the rep to add to the answer itself:

sudoers file: sudo visudo

exception added: www-data ALL=(ALL) NOPASSWD: ALL


回答 4

根据情况明确使用哪个命令

exec() -执行外部程序

system() -执行外部程序并显示输出

passthru() -执行外部程序并显示原始输出

资料来源:http : //php.net/manual/en/function.exec.php

To clarify which command to use based on the situation

exec() – Execute an external program

system() – Execute an external program and display the output

passthru() – Execute an external program and display raw output

Source: http://php.net/manual/en/function.exec.php


回答 5

就我而言,我需要在www名为的目录中创建一个新文件夹scripts。在其中scripts添加了一个名为的新文件test.py

然后sudo chown www-data:root scripts,我使用和sudo chown www-data:root test.py

然后我转到新scripts目录并使用sudo chmod +x test.py

我的test.py文件看起来像这样。请注意不同的Python版本:

#!/usr/bin/env python3.5
print("Hello World!")

从PHP,我现在这样做:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

您应该看到:Hello World!

In my case I needed to create a new folder in the www directory called scripts. Within scripts I added a new file called test.py.

I then used sudo chown www-data:root scripts and sudo chown www-data:root test.py.

Then I went to the new scripts directory and used sudo chmod +x test.py.

My test.py file it looks like this. Note the different Python version:

#!/usr/bin/env python3.5
print("Hello World!")

From php I now do this:

$message = exec("/var/www/scripts/test.py 2>&1");
print_r($message);

And you should see: Hello World!


回答 6

上述方法似乎很复杂。使用我的方法作为参考。

我有两个文件:

  • 运行.php

  • mkdir.py

在这里,我创建了一个包含GO按钮的HTML页面。每当您按下此按钮时,都会在您提到的路径中的目录中创建一个新文件夹。

运行.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
	if(isset($_POST['GO']))
	{
		shell_exec("python /var/www/html/lab/mkdir.py");
		echo"success";
	}
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");

The above methods seem to be complex. Use my method as a reference.

I have these two files:

  • run.php

  • mkdir.py

Here, I’ve created an HTML page which contains a GO button. Whenever you press this button a new folder will be created in directory whose path you have mentioned.

run.php

<html>
 <body>
  <head>
   <title>
     run
   </title>
  </head>

   <form method="post">

    <input type="submit" value="GO" name="GO">
   </form>
 </body>
</html>

<?php
	if(isset($_POST['GO']))
	{
		shell_exec("python /var/www/html/lab/mkdir.py");
		echo"success";
	}
?>

mkdir.py

#!/usr/bin/env python    
import os    
os.makedirs("thisfolder");

回答 7

这很琐碎,但只是想帮助已经遵循亚历杭德罗建议但遇到此错误的任何人:

sh:blabla.py:找不到命令

如果有人遇到该错误,那么Alejandro需要对php文件进行一些更改:

$command = escapeshellcmd('python blabla.py');

This is so trivial, but just wanted to help anyone who already followed along Alejandro’s suggestion but encountered this error:

sh: blabla.py: command not found

If anyone encountered that error, then a little change needs to be made to the php file by Alejandro:

$command = escapeshellcmd('python blabla.py');

如何在Python中执行包含Python代码的字符串?

问题:如何在Python中执行包含Python代码的字符串?

如何在Python中执行包含Python代码的字符串?

How do I execute a string containing Python code in Python?


回答 0

对于语句,请使用exec(string)(Python 2/3)或exec string(Python 2):

>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world

当需要表达式的值时,请使用eval(string)

>>> x = eval("2+2")
>>> x
4

但是,第一步应该是问自己是否真的需要。通常,执行代码应该是最后的选择:如果代码中可能包含用户输入的代码,则它很慢,很丑陋而且很危险。您应该始终首先考虑替代项,例如高阶函数,以查看它们是否可以更好地满足您的需求。

For statements, use exec(string) (Python 2/3) or exec string (Python 2):

>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world

When you need the value of an expression, use eval(string):

>>> x = eval("2+2")
>>> x
4

However, the first step should be to ask yourself if you really need to. Executing code should generally be the position of last resort: It’s slow, ugly and dangerous if it can contain user-entered code. You should always look at alternatives first, such as higher order functions, to see if these can better meet your needs.


回答 1

在示例中,使用exec函数将字符串作为代码执行。

import sys
import StringIO

# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()

code = """
def f(x):
    x = x + 1
    return x

print 'This is my output.'
"""

# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr

exec code

# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

print f(4)

s = codeErr.getvalue()

print "error:\n%s\n" % s

s = codeOut.getvalue()

print "output:\n%s" % s

codeOut.close()
codeErr.close()

In the example a string is executed as code using the exec function.

import sys
import StringIO

# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()

code = """
def f(x):
    x = x + 1
    return x

print 'This is my output.'
"""

# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr

exec code

# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

print f(4)

s = codeErr.getvalue()

print "error:\n%s\n" % s

s = codeOut.getvalue()

print "output:\n%s" % s

codeOut.close()
codeErr.close()

回答 2

eval并且exec是正确的解决方案,它们可以被用在更安全方式。

正如Python参考手册中所讨论并在教程中明确说明的那样,evalexec函数使用两个额外的参数,这些参数允许用户指定可用的全局和局部函数和变量。

例如:

public_variable = 10

private_variable = 2

def public_function():
    return "public information"

def private_function():
    return "super sensitive information"

# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len

>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12

>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined

>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters

>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined

本质上,您是在定义将在其中执行代码的命名空间。

eval and exec are the correct solution, and they can be used in a safer manner.

As discussed in Python’s reference manual and clearly explained in this tutorial, the eval and exec functions take two extra parameters that allow a user to specify what global and local functions and variables are available.

For example:

public_variable = 10

private_variable = 2

def public_function():
    return "public information"

def private_function():
    return "super sensitive information"

# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len

>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12

>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined

>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters

>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined

In essence you are defining the namespace in which the code will be executed.


回答 3

请记住,从版本3开始exec是一个功能!
因此请始终使用exec(mystring)代替exec mystring

Remember that from version 3 exec is a function!
so always use exec(mystring) instead of exec mystring.


回答 4

eval()仅用于表达,虽然eval('x+1')有效,但eval('x=1')不会起作用。在这种情况下,最好使用exec,甚至更好:尝试找到更好的解决方案:)

eval() is just for expressions, while eval('x+1') works, eval('x=1') won’t work for example. In that case, it’s better to use exec, or even better: try to find a better solution :)


回答 5

避免execeval

在Python中使用execeval受到了极大的反对。

有更好的选择

从最上面的答案(强调我的):

对于语句,请使用exec

当需要表达式的值时,请使用eval

但是,第一步应该是问自己是否真的需要。执行代码通常应该是万不得已的方法:如果它可以包含用户输入的代码,则它很慢,很丑陋而且很危险。您应该始终首先查看替代项,例如高阶函数,以查看它们是否可以更好地满足您的需求。

替代方案到exec / eval?

使用字符串中的名称设置和获取变量的值

[而 eval ]有效,但通常不建议使用对程序本身有意义的变量名。

相反,最好使用字典。

这不是惯用的

来自http://lucumr.pocoo.org/2011/2/1/exec-in-python/(重点是我的)

Python不是PHP

不要试图绕过Python的习惯用法,因为其他一些语言会做不同的事情。在Python中使用命名空间是有原因的,仅仅是因为它为您提供了该工具,exec但这并不意味着您应该使用该工具。

有危险

来自http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html(重点是我的)

因此,即使您删除了所有的全局变量和内置函数,eval也不安全!

所有这些尝试保护eval()的问题都在于它们是黑名单。他们明确删除了可能危险的内容。那是一场失败的战斗,因为如果只剩下一个项目,那么您可以攻击系统

那么,可以使eval安全吗?很难说。在这一点上,我最好的猜测是,如果您不能使用任何双下划线,那么不会造成任何伤害,因此,如果您排除任何具有双下划线的字符串,那么您是安全的。也许…

很难阅读和理解

来自http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html(重点是我):

首先,exec使人类更难阅读您的代码。为了弄清楚发生了什么,我不仅要阅读您的代码,还必须阅读您的代码,弄清楚它将生成什么字符串,然后阅读该虚拟代码。因此,如果您在团队中工作,发布开源软件或在StackOverflow之类的地方寻求帮助,那么其他人将很难为您提供帮助。而且,如果您有机会在6个月后进行该代码的调试或扩展,那么直接给自己增加难度。

Avoid exec and eval

Using exec and eval in Python is highly frowned upon.

There are better alternatives

From the top answer (emphasis mine):

For statements, use exec.

When you need the value of an expression, use eval.

However, the first step should be to ask yourself if you really need to. Executing code should generally be the position of last resort: It’s slow, ugly and dangerous if it can contain user-entered code. You should always look at alternatives first, such as higher order functions, to see if these can better meet your needs.

From Alternatives to exec/eval?

set and get values of variables with the names in strings

[while eval] would work, it is generally not advised to use variable names bearing a meaning to the program itself.

Instead, better use a dict.

It is not idiomatic

From http://lucumr.pocoo.org/2011/2/1/exec-in-python/ (emphasis mine)

Python is not PHP

Don’t try to circumvent Python idioms because some other language does it differently. Namespaces are in Python for a reason and just because it gives you the tool exec it does not mean you should use that tool.

It is dangerous

From http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html (emphasis mine)

So eval is not safe, even if you remove all the globals and the builtins!

The problem with all of these attempts to protect eval() is that they are blacklists. They explicitly remove things that could be dangerous. That is a losing battle because if there’s just one item left off the list, you can attack the system.

So, can eval be made safe? Hard to say. At this point, my best guess is that you can’t do any harm if you can’t use any double underscores, so maybe if you exclude any string with double underscores you are safe. Maybe…

It is hard to read and understand

From http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (emphasis mine):

First, exec makes it harder to human beings to read your code. In order to figure out what’s happening, I don’t just have to read your code, I have to read your code, figure out what string it’s going to generate, then read that virtual code. So, if you’re working on a team, or publishing open source software, or asking for help somewhere like StackOverflow, you’re making it harder for other people to help you. And if there’s any chance that you’re going to be debugging or expanding on this code 6 months from now, you’re making it harder for yourself directly.


回答 6

您可以使用exec完成执行代码,就像下面的IDLE会话一样:

>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']

4

You accomplish executing code using exec, as with the following IDLE session:

>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']

4

回答 7

正如其他人提到的那样,它是“ exec” ..

但是,如果您的代码包含变量,则可以使用“全局”来访问它,还可以防止编译器引发以下错误:

NameError:名称“ p_variable”未定义

exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)

As the others mentioned, it’s “exec” ..

but, in case your code contains variables, you can use “global” to access it, also to prevent the compiler to raise the following error:

NameError: name ‘p_variable’ is not defined

exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)

回答 8

使用eval


回答 9

值得一提的是,如果您要调用python文件,则该exec兄弟也存在execfile。如果您使用的第三方程序包中包含糟糕的IDE,并且您想在其程序包之外进行编码,那有时会很好。

例:

execfile('/path/to/source.py)'

要么:

exec(open("/path/to/source.py").read())

It’s worth mentioning, that’ exec‘s brother exist as well called execfile if you want to call a python file. That is sometimes good if you are working in a third party package which have terrible IDE’s included and you want to code outside of their package.

Example:

execfile('/path/to/source.py)'

or:

exec(open("/path/to/source.py").read())


回答 10

查看eval

x = 1
print eval('x+1')
->2

Check out eval:

x = 1
print eval('x+1')
->2

回答 11

我尝试了很多事情,但是唯一可行的事情如下:

temp_dict = {}
exec("temp_dict['val'] = 10") 
print(temp_dict['val'])

输出:

10

I tried quite a few things, but the only thing that work was the following:

temp_dict = {}
exec("temp_dict['val'] = 10") 
print(temp_dict['val'])

output:

10


回答 12

最合乎逻辑的解决方案是使用内置的eval()函数。另一种解决方案是将该字符串写入临时python文件并执行。

The most logical solution would be to use the built-in eval() function .Another solution is to write that string to a temporary python file and execute it.


回答 13

好吧..我知道这不是一个确切的答案,但可能是对像我一样看这个问题的人的注释。我想为不同的用户/客户执行特定的代码,但也想避免执行/评估。我最初希望将代码存储在每个用户的数据库中,然后执行上述操作。

我最终在“ customer_filters”文件夹中的文件系统上创建了文件,并使用了“ imp”模块,如果没有针对该客户应用的过滤器,它将继续进行

import imp


def get_customer_module(customerName='default', name='filter'):
    lm = None
    try:
        module_name = customerName+"_"+name;
        m = imp.find_module(module_name, ['customer_filters'])
        lm = imp.load_module(module_name, m[0], m[1], m[2])
    except:
        ''
        #ignore, if no module is found, 
    return lm

m = get_customer_module(customerName, "filter")
if m is not None:
    m.apply_address_filter(myobj)

因此,customerName =“ jj”将执行customer_filters \ jj_filter.py文件中的apply_address_filter

Ok .. I know this isn’t exactly an answer, but possibly a note for people looking at this as I was. I wanted to execute specific code for different users/customers but also wanted to avoid the exec/eval. I initially looked to storing the code in a database for each user and doing the above.

I ended up creating the files on the file system within a ‘customer_filters’ folder and using the ‘imp’ module, if no filter applied for that customer, it just carried on

import imp


def get_customer_module(customerName='default', name='filter'):
    lm = None
    try:
        module_name = customerName+"_"+name;
        m = imp.find_module(module_name, ['customer_filters'])
        lm = imp.load_module(module_name, m[0], m[1], m[2])
    except:
        ''
        #ignore, if no module is found, 
    return lm

m = get_customer_module(customerName, "filter")
if m is not None:
    m.apply_address_filter(myobj)

so customerName = “jj” would execute apply_address_filter from the customer_filters\jj_filter.py file


eval,exec和compile有什么区别?

问题:eval,exec和compile有什么区别?

我一直在研究Python代码的动态评估,并遇到eval()compile()函数,以及exec语句。

有人可以解释之间的区别evalexec怎样的不同模式,compile()适应吗?

I’ve been looking at dynamic evaluation of Python code, and come across the eval() and compile() functions, and the exec statement.

Can someone please explain the difference between eval and exec, and how the different modes of compile() fit in?


回答 0

简短答案,即TL; DR

基本上,eval用于EVAL审视你们单个动态生成的Python表达式,并exec用于EXEC动态生成的Python代码仅针对其副作用尤特。

evalexec具有以下两个区别:

  1. eval仅接受一个表达式exec可以采用具有Python语句的代码块:循环try: except:class和函数/方法def初始化等。

    Python中的表达式就是变量赋值中的值:

    a_variable = (anything you can put within these parentheses is an expression)
  2. eval 返回给定表达式的值,而exec忽略其代码中的返回值,并始终返回None(在Python 2中,它是一条语句,不能用作表达式,因此它实际上不返回任何内容)。

在1.0-2.7版本中,exec有一条声明是因为CPython需要为函数生成另一种类型的代码对象,这些代码对象用于在函数exec内部产生副作用。

在Python 3中,exec是一个函数;它的使用对使用它的函数的已编译字节码没有影响。


因此基本上:

>>> 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'exec'模式编译任何数目的语句编译成字节码隐含总是返回None,而在'eval'模式它编译一个单一表达式成字节码即返回该表达式的值。

>>> eval(compile('42', '<string>', 'exec'))  # code returns None
>>> eval(compile('42', '<string>', 'eval'))  # code returns 42
42
>>> exec(compile('42', '<string>', 'eval'))  # code returns 42,
>>>                                          # but ignored by exec

在这种'eval'模式下(eval如果传递了一个字符串,则在函数中),compile如果源代码包含语句或除单个表达式之外的任何其他内容,则会引发异常:

>>> 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

实际上,“ eval仅接受单个表达式”语句仅在将字符串(包含Python 源代码)传递给时适用eval。然后将其内部使用编译为字节码。compile(source, '<string>', 'eval')这才是真正的区别。

如果将一个code对象(包含Python 字节码)传递给execeval,则它们的行为相同,除了exec忽略返回值的事实外,它None始终会始终返回。因此eval,如果您只是将compile它先转换为字节码而不是将其作为字符串传递,则可以执行具有语句的内容:

>>> eval(compile('if 1: print("Hello")', '<string>', 'exec'))
Hello
>>>

即使已编译的代码包含语句,也可以正常工作。它仍然会返回None,因为那是从中返回的代码对象的返回值。compile

在这种'eval'模式下(eval如果传递了一个字符串,则在函数中),compile如果源代码包含语句或除单个表达式之外的任何其他内容,则会引发异常:

>>> 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

答案越长,又称血腥细节

execeval

exec函数(在Python 2中为语句)用于执行动态创建的语句或程序:

>>> program = '''
for i in range(3):
    print("Python is cool")
'''
>>> exec(program)
Python is cool
Python is cool
Python is cool
>>> 

eval函数对单个表达式执行相同的操作,返回表达式的值:

>>> a = 2
>>> my_calculation = '42 * a'
>>> result = eval(my_calculation)
>>> result
84

execeval均接受该程序/表达到无论是作为一个运行strunicodebytes对象包含源代码,或者作为一个code对象包含的Python字节码。

如果str/ unicode/ bytes包含源代码传递给exec,它等效行为与:

exec(compile(source, '<string>', 'exec'))

并且eval类似地等效于:

eval(compile(source, '<string>', 'eval'))

由于所有表达式都可以用作Python中的语句(Expr在Python 抽象语法中被称为节点;反之则不成立),exec如果不需要返回值,则可以始终使用。也就是说,您可以使用eval('my_func(42)')exec('my_func(42)'),区别在于eval返回的返回值是my_func,并将其exec丢弃:

>>> def my_func(arg):
...     print("Called with %d" % arg)
...     return arg * 2
... 
>>> exec('my_func(42)')
Called with 42
>>> eval('my_func(42)')
Called with 42
84
>>> 

2,只有exec接受包含语句,源代码一样defforwhileimport,或者class,赋值语句(又名a = 42),或整个程序:

>>> 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

双方execeval接受2个额外的位置参数- globalslocals-这是全局和局部变量的作用域,该代码看到。它们默认为globals()和,它们locals()在称为exec或的范围内eval,但任何字典都可以用于globals和,mapping用于localsdict当然包括)。这些不仅可以用于限制/修改代码中看到的变量,而且还经常用于捕获被引用exec代码创建的变量:

>>> g = dict()
>>> l = dict()
>>> exec('global a; a, b = 123, 42', g, l)
>>> g['a']
123
>>> l
{'b': 42}

(如果您显示整个的价值g,这将是更长的时间,因为execeval添加内置插件模块__builtins__来自动如果缺少它的全局变量)。

在Python 2中,该exec语句的正式语法实际上是exec code in globals, locals,如

>>> exec 'global a; a, b = 123, 42' in g, l

但是,替代语法exec(code, globals, locals)也一直被接受(见下文)。

compile

所述compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)内置的可用于加快与相同的码的重复调用execeval通过编译源到code对象预先。所述mode参数控制的那种代码片段的compile函数接受和种字节码它产生。选择是'eval''exec''single'

  • 'eval'模式需要一个表达式,并将生成字节码,运行时将返回该表达式的值:

    >>> dis.dis(compile('a + b', '<string>', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 RETURN_VALUE
  • 'exec'接受从单个表达式到整个代码模块的任何类型的python构造,并像将其作为模块顶级语句一样执行它们。代码对象返回None

    >>> dis.dis(compile('a + b', '<string>', 'exec'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 POP_TOP                             <- discard result
                  8 LOAD_CONST               0 (None)   <- load None on stack
                 11 RETURN_VALUE                        <- return top of stack
  • 'single'是一种有限形式,如果最后一条语句是表达式语句,则该格式'exec'接受包含单个语句(或多个由分隔的语句;)的源代码,生成的字节码还将该表达式的值打印repr到标准output(!)上

    一个ifelifelse链,有一个循环else,并try用它exceptelsefinally块被视为一个单独的语句。

    包含2个顶级语句的源代码片段是的错误'single',但在Python 2中存在一个错误,有时会在代码中允许多个顶级语句。只有第一个被编译;其余的将被忽略:

    在Python 2.7.8中:

    >>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    >>> a
    5

    在Python 3.4.2中:

    >>> 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

    这对于制作交互式Python Shell非常有用。但是,即使返回eval结果代码,也不返回表达式的值。

这样的最大区别execeval实际上来自compile函数及其模式。


除了将源代码编译为字节码之外,还compile支持将抽象语法树(Python代码的解析树)编译为code对象;并将源代码转换成抽象语法树(ast.parse用Python编写,仅调用compile(source, filename, mode, PyCF_ONLY_AST));这些代码用于动态修改源代码,以及动态代码创建,因为在复杂情况下,将代码作为节点树而不是文本行来处理通常会更容易。


虽然eval只允许您评估包含单个表达式的字符串,但是您可以eval使用整个语句,甚至可以是已被compile打包为字节码的整个模块。也就是说,对于Python 2,这print是一条语句,不能直接eval导致:

>>> 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

compile'exec'模式将它变成一个code对象,你就能eval 做到 ; 该eval函数将返回None

>>> code = compile('for i in range(3): print("Python is cool")',
                   'foo.py', 'exec')
>>> eval(code)
Python is cool
Python is cool
Python is cool

如果一个长相到evalexec源代码CPython的3,这是很明显的; 它们都PyEval_EvalCode使用相同的参数调用,唯一的区别是exec显式返回None

execPython 2和Python 3之间的语法差异

其中一个在Python的主要区别2exec一个声明,eval是一个内置的功能(两者都内置函数在Python 3)。众所周知exec,Python 2 中的正式语法为exec code [in globals[, locals]]

与大多数Python 2到3 移植 指南 似乎并不像 建议的那样execCPython 2中的语句也可以与看起来 完全execPython 3中的函数调用的语法一起使用。原因是Python 0.9.9具有exec(code, globals, locals)内置的在功能上!并且该内置函数在Python 1.0发布之前的某处exec语句替换。

由于这是可取的不破与Python 0.9.9向后兼容性,吉多·范罗苏姆在1993年增加了兼容性劈:如果code是长度为2或3的元组,并globalslocals未传递到exec声明,否则,code将被解释就像元组的第二个元素和第三个元素分别是globals和一样locals。即使在Python 1.4文档(在线最早可用的版本)中也没有提到兼容性hack ;因此对于移植指南和工具的许多作者并不了解,直到2012年11月再次对其进行了记录

第一个表达式也可以是长度为2或3的元组。在这种情况下,必须省略可选部分。形式exec(expr, globals)等同于exec expr in globals,而形式exec(expr, globals, locals)等同于exec expr in globals, locals。元组形式exec提供了与Python 3的兼容性,Python 3 exec是函数而不是语句。

是的,在CPython 2.7中它被方便地称为前向兼容选项(为什么使人们感到困惑,因为根本没有向后兼容选项),实际上它已经存在了二十年了

因此,虽然exec在Python 1和Python 2中是一个语句,而在Python 3和Python 0.9.9中是一个内置函数,

>>> exec("print(a)", globals(), {'a': 42})
42

在可能的每个广泛发行的Python版本中都具有相同的行为;并且也可以在Jython 2.5.2,PyPy 2.3.1(Python 2.7.6)和IronPython 2.6.1中使用(对它们的严格遵循CPython的未记录的行为表示敬意)。

在Pythons 1.0-2.7中,通过其兼容性技巧,您不能做的是将返回值存储exec到变量中:

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

(这在Python 3中也没有用,因为它exec总是返回None),或将引用传递给exec

>>> call_later(exec, 'print(42)', delay=1000)
  File "<stdin>", line 1
    call_later(exec, 'print(42)', delay=1000)
                  ^
SyntaxError: invalid syntax

某人可能实际使用过的一种模式,尽管可能性不大;

或在列表理解中使用它:

>>> [exec(i) for i in ['print(42)', 'print(foo)']
  File "<stdin>", line 1
    [exec(i) for i in ['print(42)', 'print(foo)']
        ^
SyntaxError: invalid syntax

这是对列表理解的滥用(请for改为使用循环!)。

The short answer, or TL;DR

Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.

eval and exec have these two differences:

  1. eval accepts only a single expression, exec can take a code block that has Python statements: loops, try: except:, class and function/method definitions and so on.

    An expression in Python is whatever you can have as the value in a variable assignment:

    a_variable = (anything you can put within these parentheses is an expression)
    
  2. eval returns the value of the given expression, whereas exec ignores the return value from its code, and always returns None (in Python 2 it is a statement and cannot be used as an expression, so it really does not return anything).

In versions 1.0 – 2.7, exec was a statement, because CPython needed to produce a different kind of code object for functions that used exec for its side effects inside the function.

In Python 3, exec is a function; its use has no effect on the compiled bytecode of the function where it is used.


Thus basically:

>>> 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

The compile in 'exec' mode compiles any number of statements into a bytecode that implicitly always returns None, whereas in 'eval' mode it compiles a single expression into bytecode that returns the value of that expression.

>>> eval(compile('42', '<string>', 'exec'))  # code returns None
>>> eval(compile('42', '<string>', 'eval'))  # code returns 42
42
>>> exec(compile('42', '<string>', 'eval'))  # code returns 42,
>>>                                          # but ignored by exec

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

>>> 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

Actually the statement “eval accepts only a single expression” applies only when a string (which contains Python source code) is passed to eval. Then it is internally compiled to bytecode using compile(source, '<string>', 'eval') This is where the difference really comes from.

If a code object (which contains Python bytecode) is passed to exec or eval, they behave identically, excepting for the fact that exec ignores the return value, still returning None always. So it is possible use eval to execute something that has statements, if you just compiled it into bytecode before instead of passing it as a string:

>>> eval(compile('if 1: print("Hello")', '<string>', 'exec'))
Hello
>>>

works without problems, even though the compiled code contains statements. It still returns None, because that is the return value of the code object returned from compile.

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

>>> 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

The longer answer, a.k.a the gory details

exec and eval

The exec function (which was a statement in Python 2) is used for executing a dynamically created statement or program:

>>> program = '''
for i in range(3):
    print("Python is cool")
'''
>>> exec(program)
Python is cool
Python is cool
Python is cool
>>> 

The eval function does the same for a single expression, and returns the value of the expression:

>>> a = 2
>>> my_calculation = '42 * a'
>>> result = eval(my_calculation)
>>> result
84

exec and eval both accept the program/expression to be run either as a str, unicode or bytes object containing source code, or as a code object which contains Python bytecode.

If a str/unicode/bytes containing source code was passed to exec, it behaves equivalently to:

exec(compile(source, '<string>', 'exec'))

and eval similarly behaves equivalent to:

eval(compile(source, '<string>', 'eval'))

Since all expressions can be used as statements in Python (these are called the Expr nodes in the Python abstract grammar; the opposite is not true), you can always use exec if you do not need the return value. That is to say, you can use either eval('my_func(42)') or exec('my_func(42)'), the difference being that eval returns the value returned by my_func, and exec discards it:

>>> def my_func(arg):
...     print("Called with %d" % arg)
...     return arg * 2
... 
>>> exec('my_func(42)')
Called with 42
>>> eval('my_func(42)')
Called with 42
84
>>> 

Of the 2, only exec accepts source code that contains statements, like def, for, while, import, or class, the assignment statement (a.k.a a = 42), or entire programs:

>>> 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

Both exec and eval accept 2 additional positional arguments – globals and locals – which are the global and local variable scopes that the code sees. These default to the globals() and locals() within the scope that called exec or eval, but any dictionary can be used for globals and any mapping for locals (including dict of course). These can be used not only to restrict/modify the variables that the code sees, but are often also used for capturing the variables that the executed code creates:

>>> g = dict()
>>> l = dict()
>>> exec('global a; a, b = 123, 42', g, l)
>>> g['a']
123
>>> l
{'b': 42}

(If you display the value of the entire g, it would be much longer, because exec and eval add the built-ins module as __builtins__ to the globals automatically if it is missing).

In Python 2, the official syntax for the exec statement is actually exec code in globals, locals, as in

>>> exec 'global a; a, b = 123, 42' in g, l

However the alternate syntax exec(code, globals, locals) has always been accepted too (see below).

compile

The compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) built-in can be used to speed up repeated invocations of the same code with exec or eval by compiling the source into a code object beforehand. The mode parameter controls the kind of code fragment the compile function accepts and the kind of bytecode it produces. The choices are 'eval', 'exec' and 'single':

  • 'eval' mode expects a single expression, and will produce bytecode that when run will return the value of that expression:

    >>> dis.dis(compile('a + b', '<string>', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 RETURN_VALUE
    
  • 'exec' accepts any kinds of python constructs from single expressions to whole modules of code, and executes them as if they were module top-level statements. The code object returns None:

    >>> dis.dis(compile('a + b', '<string>', 'exec'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 POP_TOP                             <- discard result
                  8 LOAD_CONST               0 (None)   <- load None on stack
                 11 RETURN_VALUE                        <- return top of stack
    
  • 'single' is a limited form of 'exec' which accepts a source code containing a single statement (or multiple statements separated by ;) if the last statement is an expression statement, the resulting bytecode also prints the repr of the value of that expression to the standard output(!).

    An ifelifelse chain, a loop with else, and try with its except, else and finally blocks is considered a single statement.

    A source fragment containing 2 top-level statements is an error for the 'single', except in Python 2 there is a bug that sometimes allows multiple toplevel statements in the code; only the first is compiled; the rest are ignored:

    In Python 2.7.8:

    >>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    >>> a
    5
    

    And in Python 3.4.2:

    >>> 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
    

    This is very useful for making interactive Python shells. However, the value of the expression is not returned, even if you eval the resulting code.

Thus greatest distinction of exec and eval actually comes from the compile function and its modes.


In addition to compiling source code to bytecode, compile supports compiling abstract syntax trees (parse trees of Python code) into code objects; and source code into abstract syntax trees (the ast.parse is written in Python and just calls compile(source, filename, mode, PyCF_ONLY_AST)); these are used for example for modifying source code on the fly, and also for dynamic code creation, as it is often easier to handle the code as a tree of nodes instead of lines of text in complex cases.


While eval only allows you to evaluate a string that contains a single expression, you can eval a whole statement, or even a whole module that has been compiled into bytecode; that is, with Python 2, print is a statement, and cannot be evalled directly:

>>> 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

compile it with 'exec' mode into a code object and you can eval it; the eval function will return None.

>>> code = compile('for i in range(3): print("Python is cool")',
                   'foo.py', 'exec')
>>> eval(code)
Python is cool
Python is cool
Python is cool

If one looks into eval and exec source code in CPython 3, this is very evident; they both call PyEval_EvalCode with same arguments, the only difference being that exec explicitly returns None.

Syntax differences of exec between Python 2 and Python 3

One of the major differences in Python 2 is that exec is a statement and eval is a built-in function (both are built-in functions in Python 3). It is a well-known fact that the official syntax of exec in Python 2 is exec code [in globals[, locals]].

Unlike majority of the Python 2-to-3 porting guides seem to suggest, the exec statement in CPython 2 can be also used with syntax that looks exactly like the exec function invocation in Python 3. The reason is that Python 0.9.9 had the exec(code, globals, locals) built-in function! And that built-in function was replaced with exec statement somewhere before Python 1.0 release.

Since it was desirable to not break backwards compatibility with Python 0.9.9, Guido van Rossum added a compatibility hack in 1993: if the code was a tuple of length 2 or 3, and globals and locals were not passed into the exec statement otherwise, the code would be interpreted as if the 2nd and 3rd element of the tuple were the globals and locals respectively. The compatibility hack was not mentioned even in Python 1.4 documentation (the earliest available version online); and thus was not known to many writers of the porting guides and tools, until it was documented again in November 2012:

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.

Yes, in CPython 2.7 that it is handily referred to as being a forward-compatibility option (why confuse people over that there is a backward compatibility option at all), when it actually had been there for backward-compatibility for two decades.

Thus while exec is a statement in Python 1 and Python 2, and a built-in function in Python 3 and Python 0.9.9,

>>> exec("print(a)", globals(), {'a': 42})
42

has had identical behaviour in possibly every widely released Python version ever; and works in Jython 2.5.2, PyPy 2.3.1 (Python 2.7.6) and IronPython 2.6.1 too (kudos to them following the undocumented behaviour of CPython closely).

What you cannot do in Pythons 1.0 – 2.7 with its compatibility hack, is to store the return value of exec into a variable:

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

(which wouldn’t be useful in Python 3 either, as exec always returns None), or pass a reference to exec:

>>> call_later(exec, 'print(42)', delay=1000)
  File "<stdin>", line 1
    call_later(exec, 'print(42)', delay=1000)
                  ^
SyntaxError: invalid syntax

Which a pattern that someone might actually have used, though unlikely;

Or use it in a list comprehension:

>>> [exec(i) for i in ['print(42)', 'print(foo)']
  File "<stdin>", line 1
    [exec(i) for i in ['print(42)', 'print(foo)']
        ^
SyntaxError: invalid syntax

which is abuse of list comprehensions (use a for loop instead!).


回答 1

  1. exec不是表达式:Python 2.x中的语句和Python 3.x中的函数。它编译并立即评估字符串中包含的一条语句或一组语句。例:

    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.
  2. eval是一个内置函数(不是语句),该函数对一个表达式求值并返回该表达式产生的值。例:

    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.
  3. compile是水平较低版本execeval。它不会执行或评估您的语句或表达式,但会返回可以执行此操作的代码对象。模式如下:

    1. compile(string, '', 'eval')返回如果您完成将执行的代码对象eval(string)。请注意,您不能在这种模式下使用语句。仅(单个)表达式有效。
    2. compile(string, '', 'exec')返回如果您完成将执行的代码对象exec(string)。您可以在此处使用任意数量的语句。
    3. compile(string, '', 'single')类似于exec模式,但是它将忽略除第一条语句以外的所有内容。请注意,带有结果的if/ else语句被视为单个语句。
  1. exec is not an expression: a statement in Python 2.x, and a function in Python 3.x. It compiles and immediately evaluates a statement or set of statement contained in a string. Example:

    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.
    
  2. eval is a built-in function (not a statement), which evaluates an expression and returns the value that expression produces. Example:

    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.
    
  3. compile is a lower level version of exec and eval. It does not execute or evaluate your statements or expressions, but returns a code object that can do it. The modes are as follows:

    1. compile(string, '', 'eval') returns the code object that would have been executed had you done eval(string). Note that you cannot use statements in this mode; only a (single) expression is valid.
    2. compile(string, '', 'exec') returns the code object that would have been executed had you done exec(string). You can use any number of statements here.
    3. compile(string, '', 'single') is like the exec mode, but it will ignore everything except for the first statement. Note that an if/else statement with its results is considered a single statement.

回答 2

exec用于语句,不返回任何内容。eval用于表达式,并返回表达式的值。

表达式表示“某事”,而语句表示“做某事”。

exec is for statement and does not return anything. eval is for expression and returns value of expression.

expression means “something” while statement means “do something”.