eval(expression,globals = None,locals = None )
参数是一个字符串
,python会使用globals字典和locals字典作为全局和局部的命名空间
,将expression当做一个python表达式(从技术上讲,是一个条件列表)进行解析和计算如果globals没有被提供,则使用python的全局命名空间。
当它和globals中有重复的部分时,locals里的定义会覆盖掉globals中的
,也就是当globals和locals中有冲突的部分时,locals说了算,它有决定权,以它的为准。如果locals没有被 提供的话,则默认为globals。
eval函数也可以被用来执行任意的代码对象
(如那些由compile()创建的对象)。在这种情况下,expression参数是一个代码对象而不是一个字符串。如果代码对象已经被‘exec‘编译为模式参数,eavl()的返回值是None。
a = 10
print(eval("a+10"))
# 输出:20
对引号中的式子进行解析
和计算。a = 10
g = {'a':5}
print(eval('a+10',g))
# 输出:15
a = 10
b = 20
c = 30
g = {'a':1,'b':2}
l = {'b':200,'c':3}
print(eval("a+b+c",g,l))
# 输出:204
g会屏蔽程序中的全局变量
的,而这里最主要的是为什么b是100呢?还记得我们在参数介绍的时候说过,当locals和globals起冲突时,locals是起决定作用的
。s="abck"
print(eval(s))
# 输出:NameError: name 'abck' is not defined
当它解析到这个表达式是不可以计算后,它就会查找它是不是一个变量的名字,如果是一个变量的名字,那么它会输出这个变量的内容
,否则就会产生这种报错。s="abck"
print(eval('s'))
#输出:abck
s='"sas"'
print(eval(s))
# 输出:sas
分析:eval首先去除单引号,eval在执行的时候是只会去除同种类型的引号的,对于单引号和双引号它是加以区分的。eval去除单引号后得到了“sas”,
这个时候程序解析到它是一个字符串,不可以计算,就输出了它。那么不禁想问,为什么上个例子中s="abck"会不行呢,这里面我们就可以看出区别了,一个是有引号括起来的,一个是没有的,引号括起来代表字符串,虽然不可以求值,但是是有意义的,可以进行输出,而没引号的便无法判断“身份”了,只能当做变量名进行解析,而abck并不是一个变量名
,所以就报错了。
同理:
s='["a","b","c"]'
print(eval(s))
# 输出:['a', 'b', 'c']
a = 10
b = 20
c = 30
s = '[a,b,c]'
print(eval(s))
# 输出:[10, 20, 30]
s = 'abs(10)'
print(eval(s))
# 输出:10
分析:对于这个程序,我们举的是一个满足计算的一个表达式,当eval剥去s的引号后,得到abs(10),然后它会对进行解析,这个解析我们前面介绍eval的时候说过,它会使用globals的内建模块__builtins__进行解析的,在这个内建模块中是有abs这个函数的
,所以对abs(10)进行了计算。
关于__builtins__模块中有哪些东西 ,我们可以这样查看
print(dir(__builtins__))