Pythonh中用json.load() json.loads()載入json資料的方法
阿新 • • 發佈:2019-01-08
最近在python裡面用json讀取json檔案,可是老是不成功,特此記錄一下。
預備知識:
def load(fp, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object."""
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``s`` (a ``str`` instance containing a JSON
document) to a Python object."""
其實我剛剛看json.load()和json.loads()程式碼定義的時候,也不知道什麼是檔案型別。什麼是字串型別,用python的type函式看一下就好了
例如:
with open("檔名") as f:
print(type(f)) # <class '_io.TextIOWrapper'> 也就是文字IO型別
result=json.load(f)
with open("檔名") as f:
line=f.readline():
print(type(line)) # <class 'str'>
result=json.loads(line)
使用方法
從以上可以看出json.load()是用來讀取檔案的,即,將檔案開啟然後就可以直接讀取。示例如下:
with open("檔名") as f:
result=json.load(f)
json.loads()是用來讀取字串的,即,可以把檔案開啟,用readline()讀取一行,然後json.loads()一行。示例如下:
#json檔案為:
{"outputs": ["pool1/7x7/ets", "pool1/7x7/rf", "pool1/10x10/ets", "pool1/10x10/rf", "pool1/13x13/ets", "pool1/13x13/rf"]}
讀取程式碼如下:
with open("檔名") as f:
line=f.readline():
result=json.loads(line)
當json檔案如下時,讀取內容是錯誤的:
{
"dataset":{
"train": {"type": "mnist", "data_set": "train", "layout_x": "tensor"},
"test": {"type": "mnist", "data_set": "test", "layout_x": "tensor"}
},
"train":{
"keep_model_in_mem":0,
"random_state":0,
"data_cache":{
"cache_in_disk":{
"default":1
},
"keep_in_mem":{
"default":0
},
"cache_dir":"/mnt/raid/fengji/gcforest/mnist/fg-tree500-depth100-3folds/datas"
}
},
"net":{
"outputs": ["pool1/7x7/ets", "pool1/7x7/rf", "pool1/10x10/ets", "pool1/10x10/rf", "pool1/13x13/ets", "pool1/13x13/rf"],
"layers":[
{
"type":"FGWinLayer",
"name":"win1/7x7",
"bottoms": ["X","y"],
"tops":["win1/7x7/ets", "win1/7x7/rf"],
"n_classes": 124,
"estimators": [
{"n_folds":3,"type":"ExtraTreesClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10},
{"n_folds":3,"type":"RandomForestClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10}
],
"stride_x": 2,
"stride_y": 2,
"win_x":7,
"win_y":7
},
{
"type":"FGWinLayer",
"name":"win1/10x10",
"bottoms": ["X","y"],
"tops":["win1/10x10/ets", "win1/10x10/rf"],
"n_classes": 10,
"estimators": [
{"n_folds":3,"type":"ExtraTreesClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10},
{"n_folds":3,"type":"RandomForestClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10}
],
"stride_x": 2,
"stride_y": 2,
"win_x":10,
"win_y":10
},
{
"type":"FGWinLayer",
"name":"win1/13x13",
"bottoms": ["X","y"],
"tops":["win1/13x13/ets", "win1/13x13/rf"],
"n_classes": 10,
"estimators": [
{"n_folds":3,"type":"ExtraTreesClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10},
{"n_folds":3,"type":"RandomForestClassifier","n_estimators":500,"max_depth":100,"n_jobs":-1,"min_samples_leaf":10}
],
"stride_x": 2,
"stride_y": 2,
"win_x":13,
"win_y":13
},
{
"type":"FGPoolLayer",
"name":"pool1",
"bottoms": ["win1/7x7/ets", "win1/7x7/rf", "win1/10x10/ets", "win1/10x10/rf", "win1/13x13/ets", "win1/13x13/rf"],
"tops": ["pool1/7x7/ets", "pool1/7x7/rf", "pool1/10x10/ets", "pool1/10x10/rf", "pool1/13x13/ets", "pool1/13x13/rf"],
"pool_method": "avg",
"win_x":2,
"win_y":2
}
]
}
}
因為在程式碼中,json.loads()並沒有讀取完整的json檔案,只是讀取了行,所以這時json.loads(line)讀取的是不合符json語法的字串,會報錯:
with open("檔名") as f:
line=f.readline(): # 這裡line只是讀取了json檔案的一行,並沒有全部讀取,所以line裡面所存的字串是不符合json語法的,所以讀取出錯。
result=json.loads(line)
Traceback (most recent call last):
File "D:/PycharmProjects/mnistCheck/test.py", line 12, in <module>
result = json.loads(row)
File "C:\ProgramData\Anaconda3\envs\tensorflow\lib\json\__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "C:\ProgramData\Anaconda3\envs\tensorflow\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\ProgramData\Anaconda3\envs\tensorflow\lib\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 2 column 1 (char 2)
那麼問題來了。。。。在實際應用中,我們會在json檔案中做註釋,比如以“//”開頭的註釋,除了註釋部分外,其他內容都是符合json語法的,那麼我們要怎麼處理呢?
def load_json(path):
import json
lines = [] # 第一步:定義一個列表, 開啟檔案
with open(path) as f:
for row in f.readlines(): # 第二步:讀取檔案內容
if row.strip().startswith("//"): # 第三步:對每一行進行過濾
continue
lines.append(row) # 第四步:將過濾後的行新增到列表中.
return json.loads("\n".join(lines)) #將列表中的每個字串用某一個符號拼接為一整個字串,用json.loads()函式載入,這樣就大功告成啦!!
今天的學習就到這裡,明天見!!