python中eval和ast.literal_eval的区别

Python中,如果要将字符串型的list,tuple,dict转变成原有的类型呢?这个时候你自然会想到eval. eval函数在Python中做数据类型的转换还是很有用的。它的作用就是把数据还原成它本身或者是能够转化成的数据类型.

string <=> list

In [1]: s = '[1, 2, 3, 4]'

In [2]: l = eval(s)

In [3]: s
Out[3]: '[1, 2, 3, 4]'

In [4]: l
Out[4]: [1, 2, 3, 4]

In [5]: type(s)
Out[5]: str

In [6]: type(l)
Out[6]: list

string <=> tuple

In [9]: s = '(1, 2, 3)'

In [10]: l = eval(s)

In [11]: s
Out[11]: '(1, 2, 3)'

In [12]: l
Out[12]: (1, 2, 3)

In [13]: type(s)
Out[13]: str

In [14]: type(l)
Out[14]: tuple

string <=> dict

In [15]: s = "{'key': 'value'}"

In [16]: d = eval(s)

In [17]: s
Out[17]: "{'key': 'value'}"

In [18]: d
Out[18]: {'key': 'value'}

In [19]: type(s)
Out[19]: str

In [20]: type(d)
Out[20]: dict

eval可以实现从元祖,列表,字典型的字符串到元祖,列表,字典的转换,此外,eval还可以对字符串型的输入直接计算。比如,她会将’1+1’的计算串直接计算出结果。

In [21]: v = eval(raw_input('Please input a string: '))
Please input a string: 1+2

In [22]: v
Out[22]: 3

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 。可以先看下stackoverflow及Python官方关于这个解释!

stackoverflow

datamap = eval(raw_input('Provide some data here: ') means that you actually evaluate the code before you deem it to be unsafe or not. It evaluates the code as soon as the function is called. See also the dangers of eval.

ast.literal_eval raises an exception if the input isn't a valid Python datatype, so the code won't be executed if it's not.

Use ast.literal_eval whenever you need eval. If you have Python expressions as an input that you want to evaluate, you shouldn't (have them).

简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的 literal_eval() 函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算。

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

报值错误,不合法的字符串!

In [24]: ast.literal_eval('1+1')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-95230a08e888> in <module>()
----> 1 ast.literal_eval('1+1')

/usr/lib/python2.7/ast.pyc in literal_eval(node_or_string)
     78                 return left - right
     79         raise ValueError('malformed string')
---> 80     return _convert(node_or_string)
     81 
     82 

/usr/lib/python2.7/ast.pyc in _convert(node)
     77             else:
     78                 return left - right
---> 79         raise ValueError('malformed string')
     80     return _convert(node_or_string)
     81 

ValueError: malformed string

In [25]: ast.literal_eval("open(r'D://filename.txt', 'r').read()")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-d422bfc7e710> in <module>()
----> 1 ast.literal_eval("open(r'D://filename.txt', 'r').read()")

/usr/lib/python2.7/ast.pyc in literal_eval(node_or_string)
     78                 return left - right
     79         raise ValueError('malformed string')
---> 80     return _convert(node_or_string)
     81 
     82 

/usr/lib/python2.7/ast.pyc in _convert(node)
     77             else:
     78                 return left - right
---> 79         raise ValueError('malformed string')
     80     return _convert(node_or_string)
     81 

ValueError: malformed string

而只会执行合法的Python类型,从而大大降低系统的危险性!

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

### 回答1: ast.literal_eval是一个函数,可以将字符串转换为对应的Python对象,例如将字符串'123'转换为整数123,将字符串'[1, 2, 3]'转换为列表[1, 2, 3]。它可以安全地解析一些简单的Python表达式,但不支持所有Python语法。使用时需要注意安全性,避免执行恶意代码。 ### 回答2: ast.literal_evalPython内置的一个函数,它用于安全地评估一个字符串类型的Python表达式,并返回表达式的值。 使用ast.literal_eval可以避免使用内置函数eval()可能引发的安全问题。eval()函数会将传入的字符串当作Python代码进行评估,如果字符串来自不可信的来源,可能会导致执行恶意代码。而ast.literal_eval会执行更严格的评估,只会允许对字面值表达式的评估,不会执行任何函数调用或表达式语句。 ast.literal_eval的使用非常简单,只需将一个合法的字符串表达式作为参数传入即可。如果字符串的语法不正确, ast.literal_eval会抛出一个值错误(SyntaxError);如果字符串包含的表达式不是有效的Python字面值,会抛出一个值错误(ValueError)。如果表达式的评估成功,ast.literal_eval会返回表达式的值。 例如,假设有一个字符串'1 + 2',如果直接用eval()函数进行评估,会抛出一个错误,因为'1 + 2'不是一个有效的Python表达式。但如果使用ast.literal_eval('1 + 2'),会抛出一个值错误,提示无效的字面值。只有当传入合法的字面值表达式时,ast.literal_eval才能正确评估并返回其值。 总之,ast.literal_eval是一个非常有用的函数,它提供了一种安全且简便的方法来评估字符串类型的Python表达式,帮助我们在处理可信和不可信的Python代码时,减少潜在的安全风险。 ### 回答3: ast.literal_eval是一个Python内置模块ast的函数,用于将字符串形式的字面值转换为对应的Python对象。它类似于内置函数eval,但有一些重要差异。 使用ast.literal_eval时,传入的参数必须是合法的Python字面值表达式,例如数字、字符串、元组、列表、字典、布尔值和None值等,否则会引发SyntaxError异常。 相比于eval函数,ast.literal_eval更加安全。因为它仅仅被用于求值字面量表达式,不会执行任何表达式的函数或变量,因此可以避免恶意代码的执行。这使得ast.literal_eval成为处理不可信输入时的一个很好的选择。 ast.literal_eval的返回值是根据传入的参数的类型而变化的,如果是字面值表达式,返回值将是对应的Python对象。例如,传入的字符串是"[1, 2, 3]",则返回一个列表 [1, 2, 3]。如果传入的字符串无法解析成合法的Python字面值,将会引发ValueError异常。 ast.literal_eval的应用场景广泛。例如,当从文件读取字符串表示的数据时,可以使用ast.literal_eval将其转换为相应的数据结构。此外,它还常用于处理JSON数据,因为JSON的数据类型与Python的数据类型非常相似,可以使用ast.literal_eval将JSON字符串转换为Python对象。 总而言之,ast.literal_eval是一个安全且高效的函数,用于将字符串形式的字面值转换为Python对象。在处理不可信输入和解析字符串数据时,ast.literal_eval可以帮助我们避免潜在的安全问题,并提供更好的代码性能和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值