亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Python如何把不同類型數據的json序列化

瀏覽:3日期:2022-06-20 16:02:27

現代網絡應用Web APP或大型網站的后臺一般只有一個,然后客戶端卻是各種各樣的(iOS, android, 瀏覽器), 而且客戶端的開發語言很可能與后臺的開發語言不一樣。這時我們需要后臺能夠提供可以跨平臺跨語言的一種標準的數據交換格式供前后端溝通(這就是Web API的作用)。如今大家最常用的跨平臺跨語言數據交換格式就是JSON(JavaScript Object Notation)了。JSON是一種文本序列化格式(它輸出的是unicode文件,大多數時候會被編碼為utf-8),人們很容易進行閱讀和編寫。python自帶的dumps方法很有用,能很容易將字典dict類型數據轉化為json格式,然后還有很多類型的數據(如日期,集合, 自定義的類和Django的QuerySet類型),我們需要自定義序列化方法才能將它們轉化為json格式。今天小編我就來對python的json模塊做下總結,并詳細介紹如何把不同類型的數據json序列化。

何謂序列化(serialization)

每種編程語言都有各自的數據類型, 將屬于自己語言的數據類型或對象轉換為可通過網絡傳輸或可以存儲到本地磁盤的數據格式(如:XML、JSON或特定格式的字節串)的過程稱為序列化(seralization);反之則稱為反序列化。

Python的JSON模塊

python自帶的json庫(無需額外安裝), 主要包含了dumps, loads, dump和load四種方法其作用分別如下所示。

json.loads() - 將json字符串轉換為python數據類型 json.dumps() - 將python數據類型轉化為json字符串 json.dump() - 將python輸入轉化為json格式存入磁盤文件 json.load() - 將磁盤文件中json格式數據轉換為python數據類型

python數據格式與json數據格式對應轉換關系如下:

Python JSON dict Object list, tuple array str string int, float, numbers True true False false None null

你注意到了嗎? 還有很多python數據類型(set, datetime)不在上表中哦。

json的模塊dumps方法介紹 - python數據的序列化

json模塊的dumps方法可以將python常用數據格式轉化為json格式。該方法還提供了很多可選參數如ident, separators, ensure_ascii, sort_keys和default參數。這些參數都非常有用,我們會稍后逐一介紹。

dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

我們先來看看一個最簡單的例子。你注意到了嗎? 生成的json格式數據外面都加了單引號,這說明dict類型數據已經轉化成了json字符串。

>>> import json>>> json.dumps({'name':'John', 'score': 112})’{'name': 'John', 'score': 112}’

如果一個dict很長,生成的json字符串會非常長,這時我們可以設置indent參數使生成的json格式數據更優美,更容易人們閱讀。代碼如下所示:

>>> import json>>> json.dumps({'name':'John', 'score': 112}, indent=4)’{n 'name': 'John',n 'score': 112n}’>>> print(json.dumps({'name':'John', 'score': 112}, indent=4)){ 'name': 'John', 'score': 112}

然而使用indent參數的代價是json字符串里增加了額外的空白,機器閱讀根本不需要它們,

即使不用indent參數,你會發現dumps生成的json字符串中的’,’號和’:’號分隔符后都會附加一個默認空白字符,我們可以通過separators參數重新指定分隔符,從而去除無用的空白字符,如下所示。這樣可以減少無用數據的的傳輸,節省帶寬增加數據傳輸速度。

>>> import json>>> json.dumps({'name':'John', 'score': 112})’{'name': 'John', 'score': 112}’# 使用separators選項>>> json.dumps({'name':'John', 'score': 112}, separators=(’,’,’:’))’{'name':'John','score':112}’

如果字符串有非ASCII字符(比如中文),它們在json序列化時都會被轉義成’uXXXX’組成的ascii字符串。如果想得到更加易讀的字符串,可以設置ensure_ascii=False。

>>> import json>>> json.dumps({'Name':'小明', 'Age': 16})’{'Name': 'u5c0fu660e', 'Age': 16}’# 設置ensure_ascii=False>>> json.dumps({'Name':'小明', 'Age': 16}, ensure_ascii=False)’{'Name': '小明', 'Age': 16}’

一般的dict默認是無序的,你還可以設置sort_keys = True對生成的json格式數據進行排序,這里就不演示了。default參數我們后面會重點介紹。

json模塊的dump,loads和load方法介紹

與dumps方法不同,json模塊的dump方法用于將生成的json數據寫入磁盤文件。其用法和dumps類似,唯一不同的是需要指定需要寫入的文件,具體用法如下所示:

import jsonwith open('json.txt', ’w’) as f: json.dump({'Name':'小明', 'Age': 16}, f, ensure_ascii=True)

json的loads方法用于將json格式數據轉化為python格式,實現數據的反序列化,如下所示。千萬別忘了在json符串外的單引號哦。

>>> import json>>> json.loads(’{'Name': '小明', 'Age': 16}’){’Name’: ’小明’, ’Age’: 16}

json的load方法與loads用法相似,不過它需要指定存有json數據的文件。

>>> import json>>> with open('json.txt', ’r’) as f: json.load(f)很多python格式數據不能直接被dumps方法序列化

很多python數據類型(比如日期,集合和自定義的類)并不能直接被dumps方法序列化,這時會出現 xxx is not JSON serializable的錯誤,如下面代碼所示。當出現類似錯誤時,我們有兩種解決方案。

通過數據類型轉換函數實現 通過繼承JSONEncoder和JSONDecoder類實現

>>> import json>>> from datetime import datetime# DateTime類型>>> json.dumps({'date':datetime.now()})Traceback (most recent call last):TypeError: Object of type ’datetime’ is not JSON serializable# 自定義的User類>>> class User(object):def __init__(self, name): self.name = name>>> json.dumps(User('John'))Traceback (most recent call last):TypeError: Object of type ’User’ is not JSON serializable解決方案一: 編寫數據類型轉換函數

該方法的工作原理是先編寫數據類型轉化函數,通過設置dumps方法里的default參數調用格式轉化函數,將dumps方法不支持的數類型先轉化為字符串格式,再實現json序列化。

# 將datetime格式數據json化>> > import json>> > from datetime import datetime>> > def date_to_str(obj):if isinstance(obj, datetime): return obj.strftime(’%Y-%m-%d %H:%M:%S’)elif isinstance(obj, date): return obj.strftime(’%Y-%m-%d’)return TypeError>> > json.dumps({'date': datetime.now()}, default=date_to_str)’{'date': '2018-09-22 21:25:42'}’# 將set類型數據json化>> > import json>> > set_data = {’my_set’: {1, 2, 3}}>> > def set_to_list(obj):if isinstance(obj, set): return list(obj)raise TypeError>> > result = json.dumps(set_data, default=set_to_list)

對于我們自定義的類, 使用dumps方法時我們一般要先編寫obj_to_dict方法,將object轉化為字典dict再JSON序列化。同理,使用loads方法對json數據反序列化時,我們還需要編寫dict_to_obj方法,通過default參數調用。下面這2段代碼是比較通用的對象(object)與字典(dict)互轉的經典代碼,請用微信收藏后再看。

# 將自定義的類轉化為字典,dumps方法使用def obj_to_dict(obj): d = {} d[’__class__’] = obj.__class__.__name__ d[’__module__’] = obj.__module__ d.update(obj.__dict__) return d# 將字典轉化為自定義的類,loads方法使用def dict_to_obj(d): if ’__class__’ in d:class_name = d.pop(’__class__’)module_name = d.pop(’__module__’)module = __import__(module_name)class_ = getattr(module, class_name)args = dict((key.encode(’ascii’), value) for key, value in d.items())instance = class_(**args) else:instance = d return instance解決方案二: 繼承JSONEncoder類和JSONDecode類

另一個解決方案是繼承JSONEncoder類和JSONDecode類定義自己的編碼Encoder類,然后使用cls=MyEncoder,來調用編碼器。比如下例中我們定義了自己的DateTimeEncoder,將日期類型數據序列化。

from datetime import datetime, dateimport jsonclass DateTimeEncoder(json.JSONEncoder): def default(self, obj):if isinstance(obj, datetime): return obj.strftime(’%Y-%m-%d %H:%M:%S’)elif isinstance(obj, date): return obj.strftime(’%Y-%m-%d’)return json.JSONEncoder.default(self, obj)json_data = {’num’: 1, ’date’: datetime.now()}print(json.dumps(json_data, cls=DateTimeEncoder))

對于自定義的對象,我們也可以通過繼承JSONEncoder類實現它的序列化,如下所示:

import jsonclass User(object): def __init__(self, name):self.name = nameclass MyJSONEncoder(json.JSONEncoder): def default(self, obj):d = {}d[’__class__’] = obj.__class__.__name__d[’__module__’] = obj.__module__d.update(obj.__dict__)return duser = User('John')json.dumps(user, cls=MyJSONEncoder))

對于簡單的數據序列化,方案一更容易理解,代碼也更少。但當需要傳輸的數據很大時,使用繼承JSONEncoder類來實現序列化時有個很大的好處,就是可以通過iterencode()方法把一個很大的數據對象分多次進行序列化,這對于網絡持續傳輸或寫入大的文件非常有用。如下所示。

>>> for chunk in MyJSONEncoder().iterencode(big_object):... print(chunk)Django特有數據類型序列化

Django編程就是是python編程,以上所介紹的序列化方法對django也是適用的。不同的是Django還有自己專屬的數據類型比如QuerySet和ValueQuerySet類型數據,還提供了更便捷的serializers類。使用serializers類可以輕易將QuerySet格式的數據轉化為json格式。

# Django Queryset數據 to Jsonfrom django.core import serializersdata = serializers.serialize('json', SomeModel.objects.all())data1 = serializers.serialize('json', SomeModel.objects.all(), fields=(’name’,’id’))data2 = serializers.serialize('json', SomeModel.objects.filter(field = some_value))

有時候我們只需要查詢結果集的部分字段,可以使用values(’字段名’,’字段名2’)來要求返回的是哪些列的數據.但是返回來的是ValuesQuerySet對象而不是QuerySet對象。ValuesQuerySet對象不能用 serializers.serialize() 方法序列化成json, 需要先轉換成list再用 json.dumps()方法序列化成json格式。示例代碼如下所示:

import jsonfrom django.core.serializers.json import DjangoJSONEncoderqueryset = myModel.objects.filter(foo_icontains=bar).values(’f1’, ’f2’, ’f3’)data4 = json.dumps(list(queryset), cls=DjangoJSONEncoder)django-rest-framework

如果你要利用django開發restful的web API, 為不同客戶端提供序列化過的json格式數據,django-rest-framework才是你真正需要的序列化工具。與django自帶的serializers類相比,rest framework支持用戶驗證,查詢過濾和符合restful規范的url設計,我們后面會專門介紹。歡迎關注我的微信。

小結

我們介紹了何為JSON序列化以及python json模塊的dumps, loads, dump和load方法。我們還介紹了如何將dumps方法不支持的數據格式(如日期,集合, 自定義的類和Django的QuerySet類型)如何通過要自定義格式轉化函數和繼承JsonEncoder類將它們轉化為json格式。希望本文對你有所幫助。喜歡的給個贊吧!

以上就是Python如何把不同類型數據的json序列化的詳細內容,更多關于python 數據json序列化的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 亚洲一区二区三区久久精品 | 免费视频爰爱太爽了 | 国产成人综合视频 | 黄片毛片在线免费看 | 区二区三区四区免费视频 | 亚洲精国产一区二区三区 | 国产午夜一级鲁丝片 | 成人一a毛片免费视频 | 亚洲视频第一页 | 美国一级大黄一片免费网站 | 亚洲福利一区福利三区 | 亚洲国产一区二区三区a毛片 | 91久久精品国产免费一区 | 免费一级片网站 | 无人精品乱码一区二区三区 | 免费一级欧美性大片 | 全免费一级毛片在线播放 | 污污美女网站 | 亚洲伦理一区二区三区 | 精品自拍视频 | 欧美三级在线免费观看 | 秘书上班和老板啪啪中文字幕 | 黄色的一级片 | a级毛片观看 | 亚洲人成在线观看一区二区 | 国产综合在线视频 | 精品亚洲视频在线观看 | 在线视频一区二区三区四区 | 九色精品高清在线播放 | 国产主播福利一区二区 | 韩国免费高清一级 | 男女激情视频国产免费观看 | 久久精品在现线观看免费15 | 国产一级毛片欧美视频 | 福利一区二区三区视频在线观看 | 亚洲一区二区综合 | 中文精品99久久国产 | 久久亚洲电影 | 色偷偷女男人的天堂亚洲网 | 九一在线完整视频免费观看 | 久久久91精品国产一区二区三区 |