在工作中我們經常會遇到資料型別之間的互轉的問題,而通常我們請求一些API藉口返回的結果就是字串,但是格式是Json的,在Python中轉為字典是最易處理的,所以這裡記錄一下在Python下把字串轉為字典的三種方法。
方法一: 通過內建函式eval
Source Code:
#!/usr/bin/env python3
#Author: nock.chen
str_info = "{'name': 'nock', 'age': 14}"
dict_info = eval(str_info)
print("string info type is -->: %s" % (type(str_info)))
print("dict info type is -->: %s" % (type(dict_info)))
複製程式碼
Result:
string info type is -->: <class 'str'>
dict info type is -->: <class 'dict'>
複製程式碼
不過使用eval有一個安全性問題,示例如下:
Source Code:
#!/usr/bin/env python3
#Author: nock.chen
str_info = input('input str info: ')
dict_info = eval(str_info)
print("dict_info is >%s< " % dict_info)
複製程式碼
Result:
input str info: __import__('os').system('ls')
collector_data.py
test.py
Download
dict_info is >0<
複製程式碼
如上所示當我們輸入__import__('os').system('ls')
的時候會列印出指令碼所存目錄下的檔案,如果傳入一個rm -rf *
之類的命令,那則會把所有改目錄下的東西刪除掉;當然我們這麼去用的場景會非常好少,也不可能有人會這麼傳值,不過這裡說明一下。
方法二: 通過json
模組處理
Source Code:
#!/usr/bin/env python3
#Author: nock.chen
import json
str_info = '{"name": "nock", "age": 18}'
dict_info = json.loads(str_info)
print("string info type is -->: %s" % (type(str_info)))
print("dict info type is -->: %s" % (type(dict_info)))
複製程式碼
Result:
string info type is -->: <class 'str'>
dict info type is -->: <class 'dict'>
複製程式碼
使用json
模組進行轉換也存在一個問題,由於json
語法規定 陣列或物件之中的字串必須使用雙引號,不能使用單引號, 官網上有一段描述是:
#!/usr/bin/env python3
#Author: nock.chen
import json
str_info = "{'name': 'nock', 'age': 18}"
dict_info = json.loads(str_info)
複製程式碼
報錯結果如下:
Traceback (most recent call last):
File "test.py", line 7, in <module>
dict_info = json.loads(str_info)
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
複製程式碼
方法三: 通過ast
模組處理
Source Code:
#!/usr/bin/env python3
#Author: nock.chen
import ast
str_info = '{"name": "nock", "age": 18}'
dict_info = ast.literal_eval(str_info)
print("string info type is -->: %s" % (type(str_info)))
print("dict info type is -->: %s" % (type(dict_info)))
s_info = "{'name': 'nock', 'age': 18}"
d_info = ast.literal_eval(s_info)
print("s info type is -->: %s" % (type(s_info)))
print("d info type is -->: %s" % (type(d_info)))
複製程式碼
Result:
string info type is -->: <class 'str'>
dict info type is -->: <class 'dict'>
s info type is -->: <class 'str'>
d info type is -->: <class 'dict'>
複製程式碼
使用ast.literal_eval
進行轉換既不存在使用json
模組進行轉換的問題,也不存在使用eval
模組進行轉換的安全性問題,因此推薦大家使用ast.literal_eval
的方法。