社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python函数eval与ast.literal_eval的区别

公众号_运维咖啡吧 • 5 年前 • 780 次点击  
阅读 7

python函数eval与ast.literal_eval的区别

一分钟学个小知识

evalast.literal_eval都可以将字符串还原成它能够转化成的数据类型,例如

>>> from ast import literal_eval
>>> 
>>> data1 = "['ops-coffee','cn']"
>>> data2 = "{'title':'运维咖啡吧','url':'https://ops-coffee.cn'}"
>>> 
>>> print(type(data1),type(data2))
<class 'str'> <class 'str'>
>>> 
>>> 
>>> 
>>> a1 = eval(data1)
>>> print(a1, type(a1))
['ops-coffee', 'cn'] <class 'list'>
>>> 
>>> a2 = eval(data2)
>>> print(a2, type(a2))
{'title': '运维咖啡吧', 'url': 'https://ops-coffee.cn'} <class 'dict'>
>>> 
>>> 
>>> 
>>> b1 = literal_eval(data1)
>>> print(b1, type(b1))
['ops-coffee', 'cn'] <class 'list'>
>>> 
>>> b2 = literal_eval(data2)
>>> print(b2, type(b2))
{'title': '运维咖啡吧', 'url': 'https://ops-coffee.cn'} <class 'dict'>
>>> 
>>> 
复制代码

除了可以对数据类型进行转换外,他们还可以对字符串的输入做处理,例如

>>> eval('1+1')
2
>>> 
>>> 
>>> literal_eval('1+1')
2
复制代码

那么他们有何区别呢?

eval会对所有他能解析的字符串都做处理,而literal_eval则会判断需要处理的内容处理后是不是合法的python类型,如果是则处理,否则不处理

例如在以下例子中

>>> std = input('please input: ')
please input: __import__('os').system('ls /')
>>> print('out: ',eval(std))
bin  boot  dev  etc lib lost+found  opt  proc  root  run  sbin  selinux  srv	static	sys  tmp  usr  var
out:  0
>>> 
复制代码

eval处理了输入的指令,这是非常危险的,在这里仅仅是用了ls查看做测试,如果是rm之类的指令后果就会很严重,而对于literal_eval则会去判断要解析的内容是否安全,不安全就报错

>>> 
>>> print('out: ',literal_eval(std))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/ast.py", line 85, in literal_eval
    return _convert(node_or_string)
  File "/usr/local/lib/python3.6/ast.py", line 84, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7f3b192a24a8>
>>> 
复制代码

所以使用literal_eval可大大降低系统风险,有着更为安全的表现

扫码关注公众号查看更多实用文章

相关文章推荐阅读:

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/62399
 
780 次点击