ホームページ >バックエンド開発 >Python チュートリアル >Pythonシリアル化のためのJSONとpickleの詳細説明

Pythonシリアル化のためのJSONとpickleの詳細説明

高洛峰
高洛峰オリジナル
2016-10-29 10:17:041475ブラウズ

JSON モジュール

JSON (JavaScript Object Notation) は軽量のデータ交換形式です。これは ECMAScript のサブセットに基づいています。 JSON は完全に言語に依存しないテキスト形式を使用しますが、C 言語ファミリー (C、C++、Java、JavaScript、Perl、Python などを含む) に似た規則も使用します。これらの特性により、JSON は理想的なデータ交換言語になります。人間にとっては読み書きが容易であり、機械にとっても解析と生成が容易です (通常、ネットワーク伝送速度を上げるために使用されます)。
JSONはPythonではそれぞれlistとdictで構成されます。

1. Python型データとJSONデータ形式を相互に変換します

Pythonシリアル化のためのJSONとpickleの詳細説明

pthon str型はJSONからunicode型に変換、Noneはnullに変換、dictはオブジェクトに対応します

2. データのエンコードとデコード

1. シンプルタイプのデータエンコードとデコード

いわゆるシンプルタイプとは、上の表にある 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: オブジェクトをシリアル化してファイルに保存する

#オブジェクトをシリアル化してファイルに保存する obj = ['foo', {'bar': ('baz', None , 1.0, 2 )}]
with open(r"c:json.txt","w+") as f:
json.dump(obj,f)

loads: シリアル化された文字列を逆シリアル化します

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. 複雑なデータ型のエンコードとデコードをカスタマイズします

たとえば、 json でデフォルトでサポートされていない datetime オブジェクトやカスタム クラス オブジェクトなどのデータ型が見つかった場合は、エンコード関数とデコード関数をカスタマイズする必要があります。カスタム コーデックを実装するには 2 つの方法があります。

1. 方法 1: エンコードおよびデコード関数をカスタマイズする

#! /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

2. 方法 2: 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 言語でコンパイルされたバージョンです。

pickle は、JSON とは異なり、複数の言語間のデータ送信には使用されず、Python オブジェクトの永続化メソッドまたは Python プログラム間でオブジェクトを転送するメソッドとしてのみ使用されます。そのため、すべての Python データ型をサポートします。

pickle によって逆シリアル化されたオブジェクトは、ディープコピーと同様に、元のオブジェクトと同等のコピー オブジェクトです。

dumps/ダンプシリアル化

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 deserialization

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モジュールの違い

1. JSONは基本的なデータ型のみを処理します。 pickle はすべての Python データ型を処理できます。

2. JSON はさまざまな言語間の文字変換に使用されます。 Pickle は、Python プログラム オブジェクトの永続化、または Python プログラム間でのオブジェクトのネットワーク送信に使用されますが、Python のバージョンが異なるとシリアル化に違いが生じる可能性があります。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。