使用过JavaScript语言的朋友应该对其中的eval函数印象深刻。没有接触过的朋友请看我详细的介绍。eval函数可以将一个字符串当做JavaScript代码执行,也就是说,可以动态执行JavaScript代码。其实Python语言也有类似的功能,这就是exec函数。
在终端中按照以下代码依次输入:
>>> exec('i = 20') >>> exec('print(i)') 20 >>> print(i * i) 400
从上面代码可以看到,调用了两次exec函数,该函数的参数是字符串类型的值,在本例中是两句合法的Python语句。exec函数成功的执行了这两条语句,并输出了最终的结果。从这点可以看出,exec函数不仅可以执行Python代码,还可以共享上下文,而且通过exec函数执行Python代码,与直接通过Python解释器执行是完全一样的。上下文都是共享的,所以最后用print函数输出i * i 的结果是400。
不过在使用exec函数执行Python代码的时候需要注意,尽可能不要让用户可以在全局作用域下执行Python代码,否则可能会与命名空间冲突。
例如下面代码:
>>> from random import randint >>> randint(1,20) 15 >>> exec('randint = 30') >>> randint(1,20) Traceback (most recent call lase): File "<stdin>",line 1,in <module> TypeError:'int' object is not callable
在上面的代码中,导入了random模块中的randint函数,该函数用于返回一个随机整数。但在用exec函数执行的Python代码中,将randint函数作为一个变量赋值了,因此在后面的代码中就无法使用randint函数随机生成整数了。为了解决这个问题,可以为exec函数指定第2个参数值,用来表示防止exec函数执行的Python代码的作用域(字典)。
>>> from random import randint >>> randint(1,20) 9 >>> scope == {} >>> exec('randint = 30',scope) >>> randint(1,20) 19 >>> scope.keys() dict_keys(['_builtins_','randint'])
在上面代码中,为exec函数指定了第2个参数(一个字典类型的变量)。这时randint = 30 设置的randint变量实际上属于scope,而不是全局的,所以与randint函数并没有冲突。使用scope.keys函数查看scope中的key,会看到randint。
下面我们在讲exec函数中的第3个参数,用于为exec函数要指定的Python代码传递参数值。
>>> a = 20 >>> args = {'a':20,'b':30} >>> scope = {} >>> exec('print(a + b)',scope,args) 50
在上面的代码中,exec函数要执行的代码是print(a + b),这的a和b是两个变量,不过这两个变量的定义代码并不是由exec函数执行的,而是在调用exec函数前通过args定义的,args是一个字典,其中有两个key:a和b,它们的值分别是20和30。exec会根据字典的key对应要执行代码中的同名变量,如果匹配,就会将字典中相应的值传入要执行的代码。
在Python语言中还有另外一个函数eval。这个函数余exec函数类似,只是eval是用于执行表达式的,并返回结果值。而exec函数并不会返回任何值,该函数只是执行Python代码。可以利用eval函数的特性实现一个可以计算表达式的计算器。另外,eval也可以像exec函数一样,指定scope和为要执行的代码传递参数值。
>>> eval('1 + 2 - 4') -1 >>> eval('2 * (6 - 4)') 4 >>> scope={'x':20} >>> args={'y':40} >>> eval('x + y',scope,args) 60
[例 3.10] 本例将利用exec函数实现一个Python控制台。可以在控制台中输入任意多条Python语句,然后按Enter键执行前面输入的所有Python语句。
scope = {} codes = "" #用于保存输入的所有代码 print(">>>",end=" ") #输出Python控制台提示符 while True: code = input("") #输入的代码 if code == "": #如果输入的是空串,会执行以前输入的所有Python代码 exec(codes,scope) #执行以前输入的所有Python代码 codes = "" #重置codes变量,以便重新输入Python代码 print(">>>",end=" ") #继续输出Python控制台提示符 continue #忽略后面的代码 codes += code + "\n" #将输入的每一行代码首尾相连,中间换行
输出结果:
>>> a = 10 b = 20 c = 30 print(a * (b + c)) 500 >>>
这个Python控制台程序与执行Python命令进入的控制台程序类似,只是并不想Python命令进入的Python控制台一样输入一条语句就执行一条语句,而是输入完了,在一起执行。
回过头来我们解释一下什么是字典,字典是集合的一种,通过关键字(key)查找值(value),在Python语言中用一对花括号({})定义字典变量,key和value之间用冒号(:)分隔,多个key-value之间用逗号分隔。关于字典,以后会更加详细的介绍。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。