【摘要】本博文介紹了何爲json模塊?爲何要用json模塊?json和python數據的相互轉換以及如何處理json默認不支持的數據類型。
1. json模塊簡介
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於ECMAScript的一個子集。在json出現之前,不同語言之前的數據交換使用的是xml。
JSON採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C、C++、Java、JavaScript、Perl、Python等)。
這些特性使JSON成爲理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(一般用於提升網絡傳輸速率)。
所以,JSON的數據我們可以將其轉換爲其他編程語言支持的數據類型,本博文就講解JSON與python的數據交換。
2. python數據轉換爲json數據類型
python轉換爲JSON數據格式的轉換規則
python 中str類型到JSON中轉爲unicode類型,None轉爲null,dict對應object;
特別要【注意】pyhton中的集合不能轉成json格式。
函數 | 描述 |
---|---|
json.dumps | 將python對象序列化成JSON字符串 |
json.dump | 將python對象序列化並保存到json文件中 |
json.dump( )和json.dumps( )是完全不同的。
json.dump( )是對json文件的讀寫操作,而json.dumps( )是對json數據的操作。
【補充】
序列化(編碼): python對象編碼成json字符串
反序列化(解碼): 將json字符串轉成python對象
json.dumps( )
下面我們就用代碼實現一下:
我們先創建一個python的users字典
users = {}
for item in range(50):
users['user%s' %(item)] = 'potizo'
我們現在要做的是把這個python下的字典轉換爲json對象。
import json
json_users = json.dumps(users)
#這裏爲了友好顯示,調用了pprint模塊的pprint方法
pprint.pprint(json_users)
print('dumps之後的類型',type(json_users))
可以看到,對users字典調用了json.dumps之後,其類型爲json字符串。
通過ctrl+點擊dumps函數,我們進去看一下這個函數如何使用,都有什麼參數可以傳?
這裏總結一下我們常用的幾個形參:
indent=4 ---------------------------------縮進爲4
#有了縮進就增強了可讀性,但是縮進空格會使數據變大
ensure_ascii=False--------------------如果顯示中文需要設置
separators=None --------------------- 修改默認分隔符#分隔符的設置應該是(‘元素分隔符’,‘key-value分隔符’)這樣的元組,默認值是(‘,’ , ‘,’)
sort_keys ----- ------------------------ 對字典的key值進行排序
我們看一下,加了這些參數之後的效果:
import json
json_users = json.dumps(users, indent=4, ensure_ascii=False, separators=(';', '-'), sort_keys=True)
print(json_users)
可以看到我們並沒有調用pprint,但是這個字符串的顯示卻通過我們的傳值縮進了4格;ensure_ascii=False由於這個字典中不含中文,所以沒有顯示效果;key-value之間的分隔符是‘-’,而每個元素之間的分隔是;
再看一下ensure_ascii=False和sort_keys=True的效果
json_users = json.dumps(users, indent=4, ensure_ascii=False, separators=(';', '-'), sort_keys=True)
中文幫我們顯示了,並且排序爲0、1、11…19、2、21…29
json_users = json.dumps(users, indent=4, separators=(';', '-'))
沒有顯示出中文,而是顯示的其文字對應的unicode編碼,並且排序爲0、1、2、3…10、11
json.dump( )
將python對象編碼爲json格式的字符串, 並保存到指定文件中
with open('doc/users.json', 'w') as f:
json.dump(users, f, indent=4, ensure_ascii=False)
3. json數據轉換爲python數據類型
json轉換爲python’數據格式的轉換規則
函數 | 描述 |
---|---|
json.loads( ) | 將序列化的json字符串反序列化爲python對象 |
json.load( ) | 將序列化字符串從文件讀取並反序列化 |
json.loads( )
loads( )函數的形參與dumps不同,dumps()是編碼與loads()是解碼
with open('doc/users.json') as f:
content = f.read()
user_obj = json.loads(content)
print(user_obj)
print('loads之後的類型',type(user_obj))
loads()與load()用法不同,但是也可以實現從json文件中讀取字符串保存到內存中,再將其解碼爲python對象。
load()
with open('doc/users.json') as f:
user_obj = json.load(f)
print(user_obj)
print('load之後的類型:',type(user_obj))
4.自定義複雜數據類型編解碼
通過上面2張圖片,我們可以看到python與json數據的相互轉換規則中也存在一些數據類型無法轉換。比如我們碰到集合對象, datetime對象,或者自定義的類對象等json默認不支持的數據類型時,我們就需要自定義編解碼函數。
下面我們就用datetime對象來舉例說明,如何實現json與python之間的複雜數據類型轉換。
python轉json:
import datetime,json
def time2str(obj):
# 用內置函數 isinstance檢查數據類型是否是datetime.datetime
if isinstance(obj,datetime.datetime):
#def strftime(self, fmt: _Text) -> str: ...
#strftime可以把datetime.datetime的類型轉還爲字符串
json_str = {'datetime':obj.strftime('%Y-%m-%d')}
return json_str
return obj
dt = datetime.datetime.now()
#但其實這個函數只是幫我們把datetime對象轉換爲了python中的字典
pyDt = time2str(dt)
print(type(pyDt),pyDt)
若要轉換爲json格式,還需要dumps()
jsonDt = json.dumps(pyDt)
print(type(jsonDt),jsonDt)
json轉python:
def str2time(jsonObj):
#判斷json對象中是否含有datetime這個子串
if 'datetime' in jsonObj:
#如果存在,拿出這個datetime對應的value值
date_str = jsonObj['datetime']
#用列表生成式將年月日的值轉爲整型
date = [int(x) for x in date_str.split('-')]
#然後調用函數生成datetime對象
dt = datetime.datetime(date[0].date[1].date[2])
return dt
return jsonObj
pyDt = json.loads(jsonDt,objetc_hook=str2time)
print(type(pyDt),pyDt)
後面的時分秒是因爲jsonDt中沒有,所以解析不出來。如果需要時分秒。。。
看代碼吧:
在time2str()函數中,加上%X
json_str = {'datetime':obj.strftime('%Y-%m-%d %X')}
在str2time()函數中,注意以下幾行需要修改
date_str,time_str = jsonObj['datetime'].split(' ')
date = [int(x) for x in date_str.split('-')]
time = [int(x) for x in time_str.split(':')]
dt = datetime.datetime(date[0],date[1],date[2],time[0],time[1],time[2])
效果爲: