eval()用法
- python中的内置函数eval(),可以将数据还原成它本身或者能转换成的数据类型,eval()可以对直接运算字符串数据。
- 将字符串类型的list,tuple,dict转变成原有的数据。
- 如str—>list
str1 = "[1, 2, 3]"
list1 = eval(str1)
print(type(str1), str1)
print(type(list1), list)
代码运行结果:
- 如str—>tuple
str1 = "(1, 2, 3)"
tuple1 = eval(str1)
print(type(str1), str1)
print(type(tuple1), tuple1)
代码运行结果:
- 如str—>dict
str1 = '{"name": "张三", "age": 20}'
dict1 = eval(str1)
print(type(str1), str1)
print(type(dict1), dict1)
代码运行结果:
- eval()可以对字符串直接运算
a = "1 + 2"
print(eval(a))
代码运行结果:
- 所以,python内置函数eval()功能很强大,可以做str与list、tuple、dict之间的转换,还可以用做计算器,可以对解析的字符串数据做处理,从而不顾带来的后果,有很大的安全隐患。
eval()缺陷
- 当用户恶意输入一些字符串,使用eval()直接运行代码时,会造成意想不到的结果。
- 如:
a = "open(r'D:\123.txt', 'w').read()"
b = "__import__('os')".system('dir')"
- 执行a,b,会对系统文件进行读写操作,显示目录结构等信息,容易造成严重后果。
eval()改进
- 使用ast模块的literal_eval()替换eval()
- ast模块可以帮助python应用来处理抽象的语法解析,literal_eval()会判断需要计算的内容计算后是不是合法的python类型,如果是,则进行运算;否则,程序报错。
- 合法的python类型
import ast
a = "1 + 2"
print(ast.literal_eval(a))
- 因为输出结果是合法的python类型,所以直接计算结果。
- 不合法的python类型
import ast
a = "__import__('os')".system('dir')"
print(ast.literal_eval(a))
代码运行结果:
总结
ast.literal_eval()只会执行合法的python类型,可以降低系统的危险性;所以出于安全性的考虑,对字符串进行类型转换的时候,最好使用literal_eval()