問題
想要將一段列表形式的字符串轉(zhuǎn)為 list
,但是擔(dān)心這個動態(tài)的字符串可能是惡意的代碼?使用 eval
將帶來安全隱患腥例。比如:
# 期望是
eval('[1, 2, 3]')
# 實際上是
eval("os.popen('rm -rf *')")
解決方案
使用 ast.literal_eval
可以很好的避免這個問題卫玖,該函數(shù)可以安全執(zhí)行僅包含文字的表達式字符串。支持的對象有字符串慌植、字節(jié)、數(shù)字义郑、元組蝶柿、列表、字典非驮、集合交汤、 布爾值、None
和 Ellipsis
劫笙。這些是可以嵌套的芙扎,比如以字典作為元素的列表:
>>> from ast import literal_eval
>>> literal_eval("[{'name': 'john', 'location': 'halo7'}]")
[{'name': 'john', 'location': 'halo7'}]
注意 literal_eval
不可以執(zhí)行任何復(fù)雜的表達式,比如包含運算符或是有索引的表達式都是不支持的填大,會直接拋出異常戒洼。這也保證了它不會執(zhí)行惡意代碼。
拓展
- 使用
literal_eval
時允华,足夠復(fù)雜或是巨大的字符串可能導(dǎo)致 Python 解釋器的崩潰圈浇,因為 Python 的 AST 編譯器是有棧深限制的 -
literal_eval
解析異常時,可能會拋出ValueError
,TypeError
,SyntaxError
,MemoryError
或RecursionError
靴寂,這取決于傳入的字符串