Python中函数eval和ast.literal_eval的区别详解

本文探讨了Python中eval函数的强大功能,包括数据类型转换和计算,但强调其潜在的安全风险。相比之下,ast.literal_eval提供了更安全的类型转换方式,只执行合法的Python表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://zhuanlan.zhihu.com/p/29881075
众所周知在Python中,如果要将字符串型的list,tuple,dict转变成原有的类型呢? 这个时候你自然会想到eval. eval函数在python中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型.下面来看看示例代码:

# str => list
a = '[1, 2, 3, 4]'
res = eval(a)
print(a, type(a))		# [1, 2, 3, 4] <class 'str'>
print(res, type(res))	# [1, 2, 3, 4] <class 'list'>

# str => dict
info1 = '{"a": "97", "b":"98", "c":"99", "d":"100"}'
info2 = "{'a':'97', 'b':'98', 'c':'99', 'd':'100'}"

res1 = ast.eval(info1)
res2 = ast.eval(info2)
print(res1, type(res1))	# {'a': '97', 'b': '98', 'c': '99', 'd': '100'} <class 'dict'>
print(res2, type(res2))	# {'a': '97', 'b': '98', 'c': '99', 'd': '100'} <class 'dict'>

此外,eval()还可以对字符串的输入直接进行计算

eval("12 + 1") 	# 13

从上面来看,eval功能可谓非常强大,即可以做string与list,tuple,dict之间的类型转换,还可以做计算器使用!更有甚者,可以对她能解析的字符串都做处理,而不顾忌可能带来的后果!所以说eval强大的背后,是巨大的安全隐患!!!
比如说,用户恶意输入下面的字符串

open(r'D://filename.txt', 'r').read()

__import__('os').system('dir')

__import__('os').system('rm -rf /etc/*')

那么eval就会不管三七二十一,显示你电脑目录结构,读取文件,删除文件…如果是格盘等更严重的操作,她也会照做不误!!!
所以这里就引出了另外一个安全处理方式ast.literal_eval
简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算。

比如说上面的计算操作,及危险操作,如果换成了ast.literal_eval(),都会拒绝执行。

所以出于安全考虑,对字符串进行类型转换的时候,最好使用ast.literal_eval()函数!

<think>好的,我现在要介绍一下Python中的eval函数。首先,我需要回忆一下eval的基本用途语法。记得eval是用来执行一个字符串表达式,并返回表达式的值。比如,eval('1 + 1')会返回2。那这个函数的具体参数是什么呢?应该是有两个可选参数吧,globalslocals,用来指定全局局部变量的命名空间。 接下来,我得考虑使用场景。比如动态执行数学表达式,或者将字符串转换为相应的Python对象。比如用户输入一个表达式,程序用eval来计算结果。但也要注意安全风险,因为eval会执行任何传入的字符串代码,如果处理不可信的输入,可能会导致代码注入攻击。比如,如果用户输入了os.system('rm -rf /')这样的字符串,eval执行后就会造成严重后果。这时候应该提醒用户避免使用eval处理不可信的数据,或者使用限制环境的globalslocals参数。 然后需要举几个例子来说明eval的用法。比如,简单的数学运算,使用变量,或者处理更复杂的表达式。例如: x = 2 print(eval('x + 3')) # 输出5 再比如,使用globals参数限制访问的变量,创建一个空的全局字典,防止访问内部变量。 另外,evalexec有什么区别呢?exec执行代码但不返回值,而eval会计算表达式并返回结果。比如,exec可以执行语句,而eval只能处理表达式。 还要提到,虽然eval在某些情况下很有用,比如动态计算表达式,但在实际开发中应该谨慎使用,尤其是在处理用户输入时。如果必须使用,应该严格限制可用的变量函数,避免安全漏洞。 总结一下,结构大致分为:定义语法、参数说明、使用示例、安全注意事项、与exec的区别,以及适用场景替代方案。确保内容准确,例子清晰,同时强调安全性。</think>### Python中的`eval`函数详解 #### 1. 基本定义 `eval`是Python内置函数,用于**执行字符串形式的Python表达式**并返回结果。 语法: ```python eval(expression, globals=None, locals=None) ``` - `expression`:字符串形式的表达式(如 `"2 + 3"`)。 - `globals` `locals`(可选):字典形式的全局/局部命名空间,用于限制变量访问。 --- #### 2. 核心用途 - **动态计算数学表达式** ```python result = eval("3 * (5 - 2) + 10") # 输出 19 ``` - **将字符串转换为Python对象** ```python my_list = eval("[1, 2, 3]") # 输出列表 [1, 2, 3] ``` - **配合变量使用** ```python x = 10 result = eval("x ** 2") # 输出 100 ``` --- #### 3. 安全风险与防范 **危险示例**: ```python eval("__import__('os').system('rm -rf /')") # 会删除系统文件! ``` **防范措施**: 通过限制`globals`参数禁用内置函数变量: ```python env = {"__builtins__": None} # 禁用所有内置函数 eval("open('test.txt')", env) # 报错:NameError(无法访问open) ``` --- #### 4. 与`exec`的区别 | 函数 | 返回值 | 适用场景 | |----------|-------------|------------------------| | `eval` | 返回表达式结果 | 处理简单表达式(如计算、类型转换) | | `exec` | 返回`None` | 执行代码块(如循环、函数定义) | ```python exec("for i in range(3): print(i)") # 输出 0 1 2 ``` --- #### 5. 替代方案 - **`ast.literal_eval`**:安全解析基础数据类型(如列表、字典)。 ```python import ast ast.literal_eval("{'name': 'Alice'}") # 返回字典 ast.literal_eval("os.system('ls')") # 报错:仅允许字面量 ``` --- #### 6. 总结 **适用场景**: - 快速计算用户输入的数学公式(需严格过滤输入)。 - 配置文件解析(如将字符串转为字典)。 **不适用场景**: - 处理不可信的用户输入。 - 需要执行多行代码或复杂逻辑时(改用`exec`或自定义解析器)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值