三分鐘學習一個小知識,還有範例直接看!
當python在做型態轉換,str轉dict、list、tuple、set或是int時,有些人會使用eval 或 ast.literal_eval,但eval是不推的,安全性是其中重要的原因。
若要單純轉換型態,我。
稍微講一下eval會說是危險原因:
# coding:utf-8
"""
輸入下方指令:
"1000"
"1+3"
"[0, 1, [2, 2]]"
"(1, 3, 5, [7])"
"{'A': 'aa', 'B': 'bb', 'C': 'cc'}"
"__import__('os').system('ls /')"
"""
std = input('please input: ')
eval_std = eval(std)
print('input: ',eval_std, type(eval_std))
以上5種輸入,下方為輸出結果:
input: 1000 <type 'int'>
input: 4 <type 'int'>
input: [0, 1, [2, 2]] <type 'list'>
input: (1, 3, 5, [7]) <type 'tuple'>
input: {'A': 'aa', 'C': 'cc', 'B': 'bb'} <type 'dict'>
bin boot cdrom dev etc home lib lib32 lib64 libx32 lost+found media mnt opt proc root run sbin snap srv swapfile sys tmp usr var VBox.log
input: 0 <type 'int'>
eval 不只是可以轉型態、將輸入做處理,甚至系統的命令都能執行!
如果今天(使用者)輸入的內容是輸入刪除文件、顯示目錄結構等命令,那是很大的危險,所以要轉型態是不建議使用eval的!(本篇不介紹惡意操作的指令有哪些)
使用下方程式:ast.literal_eval
# coding:utf-8
import ast
"""
輸入下方指令:
"1000"
"1+3" # 會報錯
"[0, 1, [2, 2]]"
"(1, 3, 5, [7])"
"{'A': 'aa', 'B': 'bb', 'C': 'cc'}"
"__import__('os').system('ls /')" # 會報錯
"""
std = input('please input: ')
ast_std = ast.literal_eval(std)
print('input: %s %s'% (ast_std, type(ast_std)))
ast.literal_eval會去判斷要解析的內容是否安全,不安全就報錯,我們只要處理報錯的處理就好,比起找回刪除的檔案或是被偷的資料,這輕鬆多了。
結論:字符串進行類型轉換,一律用ast.literal_eval()