Python eval()和exec()函数详解

news2024/11/27 16:46:21

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() 的执行范围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:深入理解 Elasticsearch 查询:过滤器查询 vs 全文搜索

如果我必须用一句话来描述 Elasticsearch,我会这样说: 当搜索遇到大规模分析时(近乎实时) Elasticsearch 是目前最受欢迎的 10 大开源技术之一。 公平地说,它包含许多本身并不独特的关键功能,但是&#xff…

ARP渗透与攻防(八)之ARP攻击防御

系列文章 ARP渗透与攻防(一)之ARP原理 ARP渗透与攻防(二)之断网攻击 ARP渗透与攻防(三)之流量分析 ARP渗透与攻防(四)之WireShark截获用户数据 ARP渗透与攻防(五)之Ettercap劫持用户流量 ARP渗透与攻防(六)之限制网速攻击 ARP渗透与攻防(七)之Ettercap Dns劫持 ARP攻击防御 …

【Linux】调试器-gdb使用

一、背景 程序的发布方式有两种,debug模式和release模式Linux gcc/g出来的二进制程序,默认是release模式要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 当我们不加 -g 选项的时候,我们生成的可执行文件的相关符…

python刷题-关于分词词频、数组排序,数组插数的题

目录标题1、对多种日期格式进行标准化2、实现英文分词计算词频-re.split、value_counts()3、中文文章分词4、统计《鹿鼎记》小说中的人名5、用1234能组成多少个互不相同且无重复数字的三位数6、两个矩阵相加7、用逗号分隔列表-join8、在升序的序列中插入一个数---重要9、对任意…

带滤波器的PID控制仿真-3(Simulink仿真)

在带滤波器的PID控制仿真-2的基础上对算例进行Simulink仿真。控制器采用积分分离PI控制,即当误差的绝对值小于等于0.80时,加入积分控制,仿真结果如图1和2所示。图1 加入滤波器时PID控制阶跃响应图2 无滤波器时PID控制阶跃响应初始化程序&…

03-你能不能自己写一个叫做java.lang.Object的类?

前言: 接着上一次02-为什么dex文件比class文件更适合移动端?的继续往下,距离上一篇已经过去快半年了,从我的博文记录中就可以清楚地看到: 转眼2023年新春假期接近尾声了,在这近半年的时间里,其…

2023英伟达显卡排名天梯图(已更新)

2023英伟达显卡排名天梯图 注意 这里没有更新4070Ti, 它的性能应该在3090和3090ti之间 Kelvin Kelvin 于 2001 年发布,是 Nvidia 千年以来第一个新的 GPU 微架构。最初的 Xbox 游戏机使用带有 Kelvin 微架构的 NV2A GPU。 GeForce 3 和 GeForce 4 系列 GPU 是采用…

nginx启动命令和停止命令

进入nginx的sbin目录下 cd /usr/local/nginx/sbin/ 1、启动nginx ./nginx 2、停止nginx两种方式 #待nginx进程处理任务完毕进行停止。 ./nginx -s quit #先查出nginx进程id再使用kill命令强制杀掉进程。 ./nginx -s stop 3、查看nginx端口 ps aux|grep nginx 4、查看ng…

机器学习——正则化线性回归和偏差/方差(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 本文使用水库水位的变化来实现正则化线性回归,以预测大坝流出的水量。后续本文将对调试学习算法进行一些诊断&#…

2023需要重点关注的四大AI方向

2023需要重点关注的四大AI方向 过去10年,人工智能从实验室走向各行各业,成为一种普遍技术应用于众多领域。根据IDC的数据,2022年全球AI市场规模达到4328亿美元,增长近20%。而Precedence Research预计,到2030年&#xf…

商业模式画布的介绍例子

选自《软件开发权威指南》商业模式画布是指一种能够帮助创业者催生创意,降低猜测,确保他们找对目标用户,合理解决问题的工具。商业模式画布不仅能够提供更多灵活多变的计划,而且更容易满足用户的需求。更重要的是,它可…

家居建材商城|基于Springboot+Vue实现家居建材商城

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

R|使用ggrepel添加文字标签

最近在用ggrepel&#xff0c;这里记录一些官网教程中的概要。与其去搜答案&#xff0c;不如过一遍软件的示例&#xff0c;大部分的问题都能迎刃而解。更详细的内容可参照官网教程&#xff1a;https://ggrepel.slowkow.com/articles/examples.html>基本用法<相比于geom_te…

python+django健身房课程预约评分系统

启动一个新项目 执行下面的命令来创建一个新的 Django 项目&#xff1a; django-admin startproject myproject 命令行工具django-admin会在安装Django的时候一起自动安装好。 执行了上面的命令以后&#xff0c;系统会为Django项目生成基础文件夹结构。 现在&#xff0c;我…

DFS(深度优先搜索)详解(概念讲解,图片辅助,例题解释,剪枝技巧)

目录 那年深夏 引入 1.什么是深度优先搜索&#xff08;DFS&#xff09;&#xff1f; 2.什么是栈&#xff1f; 3.什么是递归&#xff1f; 图解过程 问题示例 1、全排列问题 2、迷宫问题 3、棋盘问题&#xff08;N皇后&#xff09; 4、加法分解 模板 剪枝 1.简介 2.剪枝…

ASCII表

背景 ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息互换标准代码&#xff09;是一套基于拉丁字母的字符编码&#xff0c;共收录了 128 个字符&#xff0c;用一个字节就可以存储&#xff0c;它等同于国际标准 ISO/IEC 646。 ASCII…

【R语言数据科学】:多项式回归

【R语言数据科学】:多项式回归 🌸个人主页:JOJO数据科学📝个人介绍:统计学top3高校统计学硕士在读💌如果文章对你有帮助,欢迎✌关注、👍点赞、✌收藏、👍订阅专栏✨本文收录于【R语言数据科学】本系列主要介绍R语言在数据科学领域的应用包括: R语言编程基础、R语…

软件测试该怎么测?10个测试方法,带你初步了解

软件测试该怎么测&#xff1f;10个测试方法&#xff0c;带你初步了解1.需求测试2.界面测试3.功能测试4.安全性测试5.可靠性测试6.可移植性测试7.兼容性8.易用性9.压力测试10.异常场景测试当然还有很多测试方法&#xff0c;这些要根据实际不同应用场景而变化&#xff0c;这里就以…

蓝桥杯算法训练合集五 1.简单字符变换2.字母转换3.输出一个倒等腰三角形4.寻找数组中最大值5.斐波拉契数列6.高低位变换

目录 1.简单字符变换 2.字母转换 3.输出一个倒等腰三角形 4.寻找数组中最大值 5.斐波拉契数列 6.高低位变换 1.简单字符变换 问题描述 输出任意一个小写字母&#xff0c;要求输出其ASCII码&#xff0c;并输出对应的大写字母。 输入格式 从键盘输入小写字母。 输出格式 输…

【c语言进阶】动态内存管理知识大全(上)

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;c语言学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我…