就在前几天,有人提到了eval()和exec()这??两个函数,于是翻了一下Python文档。下面简单介绍一下这两个函数以及与之相关的几个函数,如globals()、locals()和compile():1、eval函数的作用:计算指定表达式的值。也就是说,要执行的Python代码只能是单一的运算表达式(注意eval不支持任何形式的赋值运算),而不是复杂的代码逻辑,类似于lambda表达式。函数定义:eval(expression,globals=None,locals=None)参数说明:expression:必填参数,可以是字符串,也可以是任意代码对象实例(可以通过编译函数创建)。如果它是一个字符串,它将被解析并解释为Python表达式(使用全局和局部命名空间的globals和locals参数)。globals:可选参数,代表全局命名空间(存放全局变量),如果提供,必须是字典对象。locals:可选参数,表示当前局部命名空间(存放局部变量),如果提供,可以是任意映射对象。如果省略此参数,它将采用与全局变量相同的值。如果全局变量和局部变量都被省略,它们将采用调用eval()函数的环境的全局命名空间和局部命名空间。返回值:如果expression是一个代码对象,创建代码对象时,compile函数的mode参数为'exec',则eval()函数的返回值为None;否则,如果expression是输出语句,例如print(),则eval()返回None;否则,表达式expression的结果就是eval()函数的返回值;示例:x=10deffunc():y=20a=eval('x+y')print('a:',a)b=eval('x+y',{'x':1,'y':2})print('b:',b)c=eval('x+y',{'x':1,'y':2},{'y':3,'z':4})print('c:',c)d=eval('print(x,y)')print('d:',d)func()输出结果:a:30b:3c:41020d:None说明输出结果:对于变量a,忽略了eval函数的globals和locals参数,所以变量x和变量y都在调用eval函数的环境范围内获取变量值,即:x=10,y=20,a=x+y=30对于变量b,eval函数只提供了globals参数,忽略了locals参数,所以locals会取globals参数的值,即:x=1,y=2,b=x+y=3对于变量c,eval函数的globals参数和locals都提供了,那么eval函数会先从所有作用域globals中寻找变量x,从局部作用域locals中寻找变量y,即:x=1,y=3,c=x+y=4对于变量d,因为print()函数不是一个没有计算结果的计算表达式,所以返回值为None2。exec函数函数的作用:动态执行Python代码。也就是说exec可以执行复杂的Python代码,不像eval函数只能计算一个表达式的值。函数定义:exec(object[,globals[,locals]])参数说明:object:必选参数,表示需要指定的Python代码。它必须是字符串或代码对象。如果object是一个字符串,这个字符串在执行之前会被解析成一组Python语句(除非出现语法错误)。如果object是一个代码对象,它就被简单地执行。globals:可选参数,同eval函数locals:可选参数,同eval函数returnvalue:exec函数的返回值始终为None。需要注意的是,exec在Python2中不是一个函数,而是一个内置的语句(statement),但是Python2中有一个execfile()函数,可以理解为Python3集成了exec语句的功能并将execfile()函数改成一个新的exec()函数:eval()函数和exec()函数的区别:eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。eval()函数可以有返回值,而exec()函数的返回值始终为None。示例1:让我们用exec函数替换示例1中的eval函数:x=10deffunc():y=20a=exec('x+y')print('a:',a)b=exec('x+y',{'x':1,'y':2})打印('b:',b)c=exec('x+y',{'x':1,'y':2},{'y':3,'z':4})print('c:',c)d=exec('print(x,y)')print('d:',d)func()输出结果:a:Noneb:Nonec:None1020d:None因为我们说过exec函数的返回值永远是None。示例2:x=10expr="""z=30sum=x+y+zprint(sum)"""deffunc():y=20exec(expr)exec(expr,{'x':1,'y':2})e??xec(expr,{'x':1,'y':2},{'y':3,'z':4})func()output:603334输出说明:第一个两个输出和上面解释的eval函数的执行过程是一样的,就不用过多解释了。关于最后一个数34,我们可以看到毫无疑问x=1,y=3。关于为什么z还是30而不是4,这个其实很简单,我们只需要了解代码执行过程,即等同于:x=1y=2deffunc():y=3z=4z=30sum=x+y+zprint(sum)func()3.globals()和locals()函数定义和函数说明:先看这两个函数的定义和文档说明globals()说明:返回代表当前全局??符号表的字典。这始终是当前模块的字典(在函数或方法内部,这是定义它的模块,而不是调用它的模块)。翻译:返回一个表示当前全局标识符表的字典。this始终是当前模块的字典(在函数或方法内部,this指的是定义函数或方法的模块,而不是调用它的模块)locals()说明:更新并返回一个表示当前局部符号的字典桌子。自由变量在函数块中调用时由locals()返回,但在类块中不返回。注意本词典内容不得修改;更改可能不会影响解释器使用的局部变量和自由变量的值。翻译:更新并返回表示当前局部标识符表的字典。free变量在函数内部被调用时,会被locals()函数返回;当类中没有调用自由变量时,locals()函数不会返回它。注意:locals()返回的字典内容不要改变;如果必须更改,则不应影响解释器使用的局部变量和自由变量。总结:globals()函数以字典的形式返回定义该函数的模块中全局作用域下的所有标识符(变量、常量等)。locals()函数以字典的形式返回当前函数中的局部作用域下面的所有标识符如果在模块中直接调用globals()和locals()函数,它们的返回值都是同一个实例1:name='Tom'age=18deffunc(x,y):sum=x+y_G=globals()_L=locals()print(id(_G),type(_G),_G)print(id(_L),type(_L),_L)func(10,20)输出结果:2131520814344
