我們知道,Python里面,json.dumps是序列化操作,json.loads是反序列化操作。當(dāng)我使用json.dumps把一個字典轉(zhuǎn)換為字符串以后,也可以使用json.loads把這個字符串轉(zhuǎn)換為字典。
那么,有沒有可能出現(xiàn)這樣的情況:某個字典,使用json.dumps轉(zhuǎn)換成了字符串s。但是當(dāng)我使用json.loads(s)時,卻會報錯?
你別不信,我們來做一個實驗。執(zhí)行下面這段代碼,打印出一段JSON字符串:
import jsontext = '''## 摘要這篇文章主要包含xx和yy## 詳情1. abc2. def'''item = {'title': '關(guān)于abc', 'raw': text}output = json.dumps(item, ensure_ascii=False)print(output)
運行效果如下圖所示:
圖片
接下來,你把下面這個字符串復(fù)制到Python里面并使用json.loads解析:
{"title": "關(guān)于abc", "raw": "## 摘要/n這篇文章主要包含xx和yy/n/n## 詳情/n1. abc/n2. def/n"}
運行效果如下圖所示:
圖片
但如果你不是復(fù)制JSON字符串后賦值,而是直接把output反序列化,它又是正常的,如下圖所示:
圖片
你以為這就很奇怪了?更奇怪的事情還在后面。現(xiàn)在把這段有問題的JSON復(fù)制到一個文件里面,使用Python來讀取這個文本,如下圖所示:
圖片
為什么現(xiàn)在又正常了?
如果你看過這篇文章:# 一日一技:怎么你的字符串跟我不一樣,那么你可以試一試使用repr來檢查一下他們有什么不同。在Jupyter里面,可以通過直接輸入變量名的方式來檢查。大家注意下圖兩個字符串的區(qū)別:
圖片
當(dāng)我從文件里面讀取JSON字符串時,字符串中的/n變成了//n,所以解析正常。但是當(dāng)我直接把字符串賦值給變量時,換行符是/n,于是解析失敗。
真正的關(guān)鍵,就是這個反斜杠。從文本文件里面讀取的時候,所有反斜杠都是普通的字符串。讀取文件以后使用repr查看,換行符就會變成//n。但直接使用變量賦值的時候,/n就會變成真正的換行符號,這里的/是轉(zhuǎn)義字符,不是普通字符串。
如果變量賦值時,手動使用雙反斜杠,或者在字符串前面加個r,讓反斜杠變成普通字符,那么這個JSON字符串又可以正常解析了。如下圖所示:
圖片
不僅是/n,任何一個JSON字符串里面包含了反斜杠,都會有這個問題。如下圖所示:
圖片
還是使用repr就能發(fā)現(xiàn)他們的差異:
圖片
所以,這個問題的本質(zhì)原因,就在于當(dāng)我們使用print()函數(shù)打印一個字符串時,打印出來的樣子跟這個字符串實際的樣子并不一樣。所以當(dāng)我們鼠標選中這個打印出來的字符串并hardcode寫到代碼里面,變量賦值時,這個字符串已經(jīng)不是原來的字符串了。所以當(dāng)有反斜杠時,就會出現(xiàn)報錯的情況。
我知道有不少同學(xué)寫代碼時喜歡使用print大法來調(diào)試,那么一定要小心這個問題。當(dāng)你定義一個字符串變量時,如果有字符串需要直接寫死到代碼里面,那么你需要注意反斜杠的問題。當(dāng)字符串有反斜杠時,要不你就在定義的前面加上r。寫成變量 = r'hardcode的字符串',要不你就把字符串先寫到文件里面,然后用Python來讀文件,獲得這個字符串,從而規(guī)避掉反斜杠的問題。
本文鏈接:http://www.tebozhan.com/showinfo-26-90666-0.html一日一技:為什么這個JSON無法解析?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com