Python eval()与exec()函数使用介绍
作者:NOGE2022 发布时间:2022-03-13 19:24:31
eval() 和 exec() 函数都属于 Python 的内置函数,由于这两个函数在功能和用法方面都有相似之处,所以将它们放到一节进行介绍。
eval() 和 exec() 函数的功能是相似的,都可以执行一个字符串形式的 Python 代码(代码以字符串的形式提供),相当于一个 Python 的解释器。二者不同之处在于,eval() 执行完要返回结果,而 exec() 执行完不返回结果(文章后续会给出详细示例)。
eval()和exec()的用法
eval() 函数的语法格式为:
eval(expression, globals=None, locals=None, /)
而 exec() 函数的语法格式如下:
exec(expression, globals=None, locals=None, /)
可以看到,二者的语法格式除了函数名,其他都相同,其中各个参数的具体含义如下:
expression:这个参数是一个字符串,代表要执行的语句 。该语句受后面两个字典类型参数 globals 和 locals 的限制,只有在 globals 字典和 locals 字典作用域内的函数和变量才能被执行。
globals:这个参数管控的是一个全局的命名空间,即 expression 可以使用全局命名空间中的函数。如果只是提供了 globals 参数,而没有提供自定义的 __builtins__,则系统会将当前环境中的 __builtins__ 复制到自己提供的 globals 中,然后才会进行计算;如果连 globals 这个参数都没有被提供,则使用 Python 的全局命名空间。
locals:这个参数管控的是一个局部的命名空间,和 globals 类似,当它和 globals 中有重复或冲突时,以 locals 的为准。如果 locals 没有被提供,则默认为 globals。
注意,__builtins__ 是 Python 的内建模块,平时使用的 int、str、abs 都在这个模块中。通过 print(dic["__builtins__"]) 语句可以查看 __builtins__ 所对应的 value。
首先,通过如下的例子来演示参数 globals 作用域的作用,注意观察它是何时将 __builtins__ 复制 globals 字典中去的:
dic={}#定义一个字典
dic['b']=3#在 dic 中加一条元素,key 为 b
print(dic.keys())#先将 dic 的 key 打印出来,有一个元素 b
exec("a = 4", dic)#在 exec 执行的语句后面跟一个作用域 dic
print(dic.keys())#exec 后,dic 的 key 多了一个
运行结果为:
dict_keys(['b'])
dict_keys(['b', '__builtins__', 'a'])
上面的代码是在作用域 dic 下执行了一句 a = 4 的代码。可以看出,exec() 之前 dic 中的 key 只有一个 b。执行完 exec() 之后,系统在 dic 中生成了两个新的 key,分别是 a 和 __builtins__。其中,a 为执行语句生成的变量,系统将其放到指定的作用域字典里;__builtins__ 是系统加入的内置 key。
locals参数的用法就很简单了,举个例子:
a=10
b=20
c=30
g={'a':6,'b':8}#定义一个字典
t={'b':100,'c':10}#定义一个字典
print(eval('a+b+c', g, t))#定义一个字典 116
输出结果为:
116
exec()和eval()的区别
前面已经讲过,它们的区别在于,eval() 执行完会返回结果,而 exec() 执行完不返回结果。举个例子:
a =1
exec("a = 2")#相当于直接执行 a=2
print(a)
a =exec("2+3")#相当于直接执行 2+3,但是并没有返回值,a 应为 None
print(a)
a =eval('2+3')#执行 2+3,并把结果返回给 a
print(a)
运行结果为:
2
None
5
可以看出,exec() 中最适合放置运行后没有结果的语句,而 eval() 中适合放置有结果返回的语句。
如果 eval() 里放置一个没有结果返回的语句会怎样呢?例如下面代码:
a=eval("a = 2")
这时 Python 解释器会报 SyntaxError 错误,提示 eval() 中不识别等号语法。
eval() 和 exec() 函数的应用场景
在使用 Python 开发服务端程序时,这两个函数应用得非常广泛。例如,客户端向服务端发送一段字符串代码,服务端无需关心具体的内容,直接跳过 eval() 或 exec() 来执行,这样的设计会使服务端与客户端的耦合度更低,系统更易扩展。
另外,如果读者以后接触 TensorFlow 框架,就会发现该框架中的静态图就是类似这个原理实现的:
TensorFlow 中先将张量定义在一个静态图里,这就相当将键值对添加到字典里一样;
TensorFlow 中通过 session 和张量的 eval() 函数来进行具体值的运算,就当于使用 eval() 函数进行具体值的运算一样。
需要注意的是,在使用 eval() 或是 exec() 来处理请求代码时,函数 eval() 和 exec() 常常会被黑客利用,成为可以执行系统级命令的入口点,进而来攻击网站。解决方法是:通过设置其命名空间里的可执行函数,来限制 eval() 和 exec() 的执行范围。
来源:https://blog.csdn.net/m0_74309242/article/details/128769720


猜你喜欢
- 认证支持中间件中间件类: django.contrib.auth.middleware.AuthenticationMiddleware .
- 前言在数据分析领域,最热门的莫过于Python和R语言,本文将详细给大家介绍关于Python利用pandas查询数据的相关内容,分享出来供大
- --PK select * from sys.key_constraints where object_id = OBJECT_ID(
- 本文是对《Python Qt GUI快速编程》的第9章的堆叠窗口例子Vehicle Rental用Python3+PyQt5+Qt Desi
- os.path.dirname() 获取父目录os.path.basename() #获取文件名或者文件夹名python2缺省为相对路径导入
- 基于python代码的3D地图可视化,供大家参考,具体内容如下介绍使用Python对地图进行3D可视化。以地图为地图,可以在三维空间对轨迹、
- 在flask更新到1.0之后的版本,官方推荐使用flask run的方式运行程序,可是作为开发,如果没有了pycharm的断点调试,这可太难
- 近来,越来越多的数据科学家开始使用Python,我不由得想到,尽管他们从pandas、scikit-learn和numpy这些库中得到了不少
- 前言因为有一些网站需要每日检查是否有问题,所以需要一个报警监控的机制,这个需要你指定你发送的邮箱和你接收的邮箱,就可以做到对网站自动监控了。
- 但有时候,需要当某事件触发时,我们先做一些操作,然后再跳转,这时,就要用JAVASCRIPT来实现这一跳转功能。 下面是具体的做法: 一:跳
- 前言大部分初学编程的人来说刚开始都会练习判断两个数或者三个数的大小,来熟悉某种语言的特性和最基本的if,else循环,当我们学习了更高级的语
- 关于作者 王丹丹 , IBM 中国系统与技术中心软件工程师,自从 2006 年加入 IBM,一直从事 Web 系统设计和开发工作,有五年 P
- 前几天,GitHub 有个开源项目特别火,只要输入标题就可以生成一篇长长的文章。背后实现代码一定很复杂吧,里面一定有很多高深莫测的机器学习等
- 半透明效果有时候会给页面增加不少色彩,特别是Vista盛行之后,半透明效果更加受推崇。在诸多可用于Web浏览的图片格式中,只有PNG格式和G
- 目录什么是 JSON在哪里使用JSON基本的 JSON 语法如何在 Python 中处理 JSON 数据包含 JSON 模块使用 json.
- 许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪。在.NET平台中,有非常著名的第三方开
- 1.如果客户端和服务器端的连接需要跨越并通过不可信任的网络,那么就需要使用SSH隧道来加密该连接的通信。2.用set password语句来
- 1.在浏览器上搜索PyCharmhttps://www.jetbrains.com/pycharm/download/#section=wi
- jwt的问题首先说明一个jwt存在的问题,也就是要替换jwt的原因:jwt无法在服务端主动退出的问题jwt无法作废已颁布的令牌,只能等到令牌
- JIRA介绍: JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪、需求