Python將字串轉為字典最佳實踐

諾克大叔發表於2018-06-28

在工作中我們經常會遇到資料型別之間的互轉的問題,而通常我們請求一些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語法規定 陣列或物件之中的字串必須使用雙引號,不能使用單引號, 官網上有一段描述是:

Python將字串轉為字典最佳實踐
報錯示例如下:

#!/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的方法。

Python將字串轉為字典最佳實踐

相關文章