python 序列化之JSON和pickle詳解

JSON模塊

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於ECMAScript的一個子集。 JSON採用徹底獨立於語言的文本格式,可是也使用了相似於C語言家族的習慣(包括C、C++、Java、JavaScript、Perl、Python等)。這些特性使JSON成爲理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(通常用於提高網絡傳輸速率)。
JSON在python中分別由list和dict組成。python

1、python類型數據和JSON數據格式互相轉換

pthon 中str類型到JSON中轉爲unicode類型,None轉爲null,dict對應objectjson

2、數據encoding和decoding

一、簡單類型數據編解碼網絡

所謂簡單類型就是指上表中出現的python類型。函數

dumps:  將對象序列化編碼

#coding:utf-8
import json

# 簡單編碼===========================================
print json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
# ["foo", {"bar": ["baz", null, 1.0, 2]}]

#字典排序
print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
# {"a": 0, "b": 0, "c": 0}

#自定義分隔符
print json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':'))
# [1,2,3,{"4":5,"6":7}]
print json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=('/','-'))
# [1/2/3/{"4"-5/"6"-7}]

#增長縮進,加強可讀性,但縮進空格會使數據變大
print json.dumps({'4': 5, '6': 7}, sort_keys=True,indent=2, separators=(',', ': '))
# {
#   "4": 5,
#   "6": 7
# }

# 另外一個比較有用的dumps參數是skipkeys,默認爲False。
# dumps方法存儲dict對象時,key必須是str類型,若是出現了其餘類型的話,那麼會產生TypeError異常,若是開啓該參數,設爲True的話,會忽略這個key。
data = {'a':1,(1,2):123}
print json.dumps(data,skipkeys=True)
#{"a": 1}

dump:  將對象序列化並保存到文件spa

#將對象序列化並保存到文件
obj = ['foo', {'bar': ('baz', None, 1.0, 2)}]
with open(r"c:\json.txt","w+") as f:
    json.dump(obj,f)

 

loads:  將序列化字符串反序列化code

import json

obj = ['foo', {'bar': ('baz', None, 1.0, 2)}]
a= json.dumps(obj)
print json.loads(a)
# [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]

 load:  將序列化字符串從文件讀取並反序列化對象

with open(r"c:\json.txt","r") as f:
    print json.load(f)

 

3、自定義複雜數據類型編解碼

例如咱們碰到對象datetime,或者自定義的類對象等json默認不支持的數據類型時,咱們就須要自定義編解碼函數。有兩種方法來實現自定義編解碼。blog

一、方法一:自定義編解碼函數排序

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import datetime,json

dt = datetime.datetime.now()



def time2str(obj):
    #python to json
    if isinstance(obj, datetime.datetime):
        json_str = {"datetime":obj.strftime("%Y-%m-%d %X")}
        return json_str
    return obj

def str2time(json_obj):
    #json to python
    if "datetime" in json_obj:
        date_str,time_str = json_obj["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])
        return dt
    return json_obj


a = json.dumps(dt,default=time2str)
print a
# {"datetime": "2016-10-27 17:38:31"}
print json.loads(a,object_hook=str2time)
# 2016-10-27 17:38:31

二、方法二:繼承JSONEncoder和JSONDecoder類,重寫相關方法

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import datetime,json

dt = datetime.datetime.now()
dd = [dt,[1,2,3]]

class MyEncoder(json.JSONEncoder):
    def default(self,obj):
        #python to json
        if isinstance(obj, datetime.datetime):
            json_str = {"datetime":obj.strftime("%Y-%m-%d %X")}
            return json_str
        return obj

class MyDecoder(json.JSONDecoder):
    def __init__(self):
        json.JSONDecoder.__init__(self, object_hook=self.str2time)

    def str2time(self,json_obj):
        #json to python
        if "datetime" in json_obj:
            date_str,time_str = json_obj["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])
            return dt
        return json_obj


# a = json.dumps(dt,default=time2str)
a =MyEncoder().encode(dd)
print a
# [{"datetime": "2016-10-27 18:14:54"}, [1, 2, 3]]
print MyDecoder().decode(a)
# [datetime.datetime(2016, 10, 27, 18, 14, 54), [1, 2, 3]]

 

===========================================================

pickle模塊

python的pickle模塊實現了python的全部數據序列和反序列化。基本上功能使用和JSON模塊沒有太大區別,方法也一樣是dumps/dump和loads/load。cPickle是pickle模塊的C語言編譯版本相對速度更快。

與JSON不一樣的是pickle不是用於多種語言間的數據傳輸,它僅做爲python對象的持久化或者python程序間進行互相傳輸對象的方法,所以它支持了python全部的數據類型。

pickle反序列化後的對象與原對象是等值的副本對象,相似與deepcopy。

dumps/dump序列化

from datetime import date

try:
    import cPickle as pickle    #python 2
except ImportError as e:
    import pickle   #python 3


src_dic = {"date":date.today(),"oth":([1,"a"],None,True,False),}
det_str = pickle.dumps(src_dic)
print det_str
# (dp1
# S'date'
# p2
# cdatetime
# date
# p3
# (S'\x07\xe0\n\x1b'
# tRp4
# sS'oth'
# p5
# ((lp6
# I1
# aS'a'
# aNI01
# I00
# tp7
# s.
with open(r"c:\pickle.txt","w") as f:
    pickle.dump(src_dic,f)

loads/load反序列化

from datetime import date

try:
    import cPickle as pickle    #python 2
except ImportError as e:
    import pickle   #python 3


src_dic = {"date":date.today(),"oth":([1,"a"],None,True,False),}
det_str = pickle.dumps(src_dic)
with open(r"c:\pickle.txt","r") as f:
    print pickle.load(f)
# {'date': datetime.date(2016, 10, 27), 'oth': ([1, 'a'], None, True, False)}

 

JSON和pickle模塊的區別

一、JSON只能處理基本數據類型。pickle能處理全部Python的數據類型。

二、JSON用於各類語言之間的字符轉換。pickle用於Python程序對象的持久化或者Python程序間對象網絡傳輸,但不一樣版本的Python序列化可能還有差別。

相關文章
相關標籤/搜索