第6.4节 Python动态表达式计算:eval函数详述

在Python动态执行的函数中,eval是用于执行表达式计算的函数,这个函数用于执行字符串中包含的一个表达式或其编译后对应的代码,不能适用于执行Python语句和完整的代码。

一、    语法
1、    语法:eval(expression, globals=None, locals=None)
2、    参数说明:
1)    expression实参是一个字符串或compile编译好的表达式代码,如果是编译的代码,必须编译时模式指定为‘eval’,否则函数执行后返回None;
2)    globals:全局名字空间,必须是一个字典,可选参数;
3)    locals:局部名字空间或称为本地名字空间,可以是任何映射对象如字典。
特别说明:
4)    前面已经介绍了名字空间的概念,名字空间用字典类型来定义,此时在名字空间中的变量名就是该字典的键,变量值则是该键对应的值;
5)    如果省略 locals 字典则其默认值为 globals 字典。 如果两个字典同时省略,表达式会在 eval() 被调用的环境中执行;
6)    如果执行eval时,表达式中存在变量,则该变量的查找步骤为:去局部名字空间中查找->去全局名字空间中查找->去当前执行代码的空间查找。如果有一个步骤找到,则直接取该变量参与运算,否则到下一个名字空间中查找,都找不到则报错
3、    返回值:
1)    当正常执行时返回表达式对应的计算结果,语法错误将作为异常处理。
二、    举例:三种加法实现
1、    第一种方式:字符串表达式执行,没有使用全局空间和局部空间,不编译

def add1(a,b):  # 
    s='a+b'
    return eval(s)
        此时执行调用add1(1,2)返回3


2、    第二种方式:字符串表达式编译后执行,没有使用全局空间和局部空间

def add2(a,b):
s='a+b'
    c=compile(s,'<expression string>','eval')
    return eval(c)    


此时执行调用add2(1,2)返回3
3、    第三种方式:带全局空间和局部空间的字符串表达式编译后执行

def add3(a,b):
    s='a+b'
    c=compile(s,'<expression string>','eval')
    gArea,lArea = {},{}
    gArea['a']=str(a*10)
    gArea['b']=str(b*10)
lArea['a']=str(a*100)
    return eval(c,gArea,lArea)    #指定全局名字空间和局部名字空间


此时执行调用add3(1,2)返回’10020’。为什么是’10020’?我们一步步来解释:
1)    首先函数定义了2个参数和一个局部变量加法字符串,他们在函数所在的名字空间,经调用传参时,a=1,b=2;
2)    编译表达式(不编译直接执行字符串效果相同);
3)    下面定义了执行字符串对应代码的全局名字空间和局部名字空间gArea,lArea;
4)    给全局空间的变量a赋值为a*10(a=1)结果对应字符串‘10’,变量b赋值为字符串’20’;
5)    给局部名字空间的变量a赋值为’100’;
6)    此时执行编译代码,就是执行变量a+变量b,按照上面介绍的查找变量的方法,在局部名字空间中找到变量a,在全局名字空间中找到变量b,二者都是字符串,相加变成了字符串’100’+’20’的拼接,返回字符串’10020’
三种方法执行截屏:
 
本节老猿详细介绍了动态执行的eval函数及各个参数,并结合例子介绍了相关方法的使用。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!

原文地址:https://www.cnblogs.com/LaoYuanPython/p/11087715.html