python でpickleをJSONに保存する
pickle.dump で得たバイナリを16進数文字列に変換してその文字列を保存します
データベースのテキストフィールドにクラスオブジェクトを保存したかったというのが本記事の動機です
出力処理
対象オブジェクトを pickle.dump し、そのバイナリを16進数文字列に変換します
def ObjectToJSON(obj):
out = io.BytesIO()
pickle.dump(obj, out)
buf = out.getbuffer()
hexBin = codecs.encode(buf, 'hex')
hexStr = hexBin.decode("utf-8")
return json.dumps(hexStr)
入力処理
出力処理で作成した16進数文字列をバイナリに変換しそれを pickle.load に与えます
def JSONToObject(jsonStr):
hexStr = json.loads(jsonStr)
bin = bytes.fromhex(hexStr)
input = io.BytesIO(bin)
obj = pickle.load(input)
return obj
実験ソースコード
import codecs
import copy
import io
import json
import numpy as np
import pickle
class Hoge:
def __init__(self):
self.a = 0
self.b = 0.0
self.c = ""
self.d = np.zeros(10)
def DumpVars(self):
for k in vars(self):
print(k, self.__dict__[k])
def ObjectToJSON(obj):
out = io.BytesIO()
pickle.dump(obj, out)
buf = out.getbuffer()
hexBin = codecs.encode(buf, 'hex')
hexStr = hexBin.decode("utf-8")
return json.dumps(hexStr)
def JSONToObject(jsonStr):
hexStr = json.loads(jsonStr)
bin = bytes.fromhex(hexStr)
input = io.BytesIO(bin)
obj = pickle.load(input)
return obj
def Test1():
print("# Test1")
x = Hoge()
x.a = 1
x.b = 1.2345
x.c = "ほげ"
x.d = np.repeat(np.arange(3), 4).reshape(3, 4)
x.DumpVars()
jsonStr = ObjectToJSON(x)
print(jsonStr)
def Test2():
print("# Test2")
jsonStr = '"8003635f5f6d61696e5f5f0a486f67650a7100298171017d71022858010000006171034b015801000000627104473ff3c083126e978d58010000006371055806000000e381bbe3819271065801000000647107636e756d70792e636f72652e6d756c746961727261790a5f7265636f6e7374727563740a7108636e756d70790a6e6461727261790a71094b0085710a430162710b87710c52710d284b014b034b0486710e636e756d70790a64747970650a710f5802000000693871108988877111527112284b0358010000003c71134e4e4e4affffffff4affffffff4b007471146289436000000000000000000000000000000000000000000000000000000000000000000100000000000000010000000000000001000000000000000100000000000000020000000000000002000000000000000200000000000000020000000000000071157471166275622e"'
x = JSONToObject(jsonStr)
x.DumpVars()
def main():
Test1()
Test2()
if __name__ == "__main__":
main()
以上です