Python——序列化模塊

1. 序列化與反序列化

序列化 :數據類型-->字符串
反序列化:字符串-->數據類型python

2. 序列化模塊

模塊 重要程度 簡單介紹
json ***** 通用的序列化格式(各類編程語言都用)
pickle **** 全部的python數據類型均可以經過pickle轉化爲字符串
shelve *** 使用句柄直接操做,很方便

 

(1)json 

    優勢:通用的序列化格式
  缺點:只有不多一部分數據類型能夠經過json轉化爲字符串編程

  json —— 數字、字符串、列表、字典、元祖(被看成列表處理)json

  <1> 直接操做內存中的數據類型——dumps loadsapp

import json
dic = {'k1':'v1'}
print(type(dic),dic)    # <class 'set'> {'k1', 'v1'}

# dumps序列化方法
str_d = json.dumps(dic) #序列化
print(type(str_d),str_d)    # <class 'str'> {"k1": "v1"}
# json 自己是''   因此其內部字符串都用 ""       舉例:{"k1": "v1"}
# loads反序列化方法
dic_d = json.loads(str_d)   #反序列化
print(type(dic_d),dic_d)    #<class 'dict'> {'k1': 'v1'}
View Code

   <2> 和文件相關的操做——dump load編程語言

# dump的參數ensure_ascii

import json
dic = {1:'中國',2:'b'}
f = open('file','w',encoding='utf-8')
# dump方法
json.dump(dic,f)        # 成功寫入文件,ensure_ascii默認爲True {"1": "\u4e2d\u56fd", "2": "b"}
json.dump(dic,f,ensure_ascii=False)        # 成功寫入文件 {'1': '中國', '2': 'b'}
f.close()
# load方法
f = open('file','r',encoding='utf-8')
res = json.load(f)      # 成功讀取文件 {'1': '中國', '2': 'b'}
f.close()
print(type(res),res)     # <class 'dict'> {'1': '中國', '2': 'b'}
View Code
# 一次性寫進去dump,再一次性讀出來load

import json
dic = {1:'a',2:'b'}
f = open('file','w',encoding='utf-8')
# dump方法
json.dump(dic,f)        # 成功寫入文件 {"1": "a", "2": "b"}
f.close()
# load方法
f = open('file','r')
res = json.load(f)      # 成功讀取文件 {'1': 'a', '2': 'b'}
f.close()
print(type(res),res)     # <class 'dict'> {'1': 'a', '2': 'b'}
View Code
# 一次寫進去一行dumps,再一行一行讀出來loads

import json

l = [{'k1':111},{'k2':1111},{'k3':11}]
f = open('f','w')

for dic in l:
    str_dic = json.dumps(dic)
    f.write(str_dic+'\n')
f.close()

f = open('f')
import json
l = []
for line in f:
    dic = json.loads(line.strip())     # strip去空格,去換行符
    l.append(dic)
f.close()
print(l)
View Code

(2)pickle

  優勢:全部的python數據類型均可以經過pickle轉化爲字符串
  缺點:pickle序列化的內容只有python能理解;且部分反序列化依賴python代碼ide

  <1> 直接操做內存中的數據類型——dumps loadsthis

import pickle

dic = {'k1':'v1'}
print(type(dic),dic)    # <class 'set'> {'k1', 'v1'}

# dumps序列化方法
str_dic = pickle.dumps(dic) #序列化
print(type(str_dic),str_dic)    # 一串二進制內容 <class 'bytes'> b'\x80\x03}q\x00X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02s.'

# loads反序列化方法
dic_d = pickle.loads(str_dic)   #反序列化
print(type(dic_d),dic_d)    # 字典 <class 'dict'> {'k1': 'v1'}
View Code

  <2> 和文件相關的操做——dump load  【文件操做形式要加b,由於是bytes類型的】spa

import pickle
import time

struct_time = time.localtime(1000000000)
print(struct_time)
f = open('pickle_file','wb')
# dump方法
pickle.dump(struct_time,f)        # 成功寫入文件,time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0)

f.close()
# load方法
f = open('pickle_file','rb')
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)     # 2001
f.close() 
View Code

  <3> pickle 能夠分步dump和load,json不能夠code

import pickle
import time

struct_time1 = time.localtime(1000000000)
struct_time2 = time.localtime(1000000000)
print(struct_time1)     # time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0)
print(struct_time2)     # time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=9, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0)
f = open('pickle_file','wb')
# dump方法
pickle.dump(struct_time1,f)        # 寫入文件
pickle.dump(struct_time2,f)        # 寫入文件
f.close()
# load方法
f = open('pickle_file','rb')
struct_time1 = pickle.load(f)
struct_time2 = pickle.load(f)
print(struct_time1.tm_year)     # 2001
print(struct_time2.tm_year)     # 2001
f.close()
View Code

(3)shelve

  優勢:序列化句柄,使用句柄直接操做,很方便
  缺點:新模塊,有小問題,不夠完善對象

import shelve

f = shelve.open('shelve_file')
f['key'] = {'int':10,'float':9.5,'string':'Sample data'}    # 直接對文件句柄操做,就能夠存入數據
f.close()

f = shelve.open('shelve_file')
existing = f['key']     # 取出數據時只須要直接用key獲取,key不存在就報錯
f.close()
print(existing)     #{'int': 10, 'float': 9.5, 'string': 'Sample data'}
View Code

  <1> 不支持多個應用同一時間往同一個DB進行寫操做

import shelve

f = shelve.open('shelve_file','r')  # 只進行讀操做時,經過只讀方式打開
existing = f['key']
f.close()
print(existing)     # {'int': 10, 'float': 9.5, 'string': 'Sample data'}
View Code

  <2> 小問題:只讀的時候能夠修改

import shelve

f = shelve.open('shelve_file','r')  # 只進行讀操做時,經過只讀方式打開
existing = f['key']
print(existing)     # 100
# f['key']= 100
f['key']= 111
f.close()

f = shelve.open('shelve_file','r')  # 只進行讀操做時,經過只讀方式打開
existing2 = f['key']
f.close()
print(existing2)     # 111
View Code

  <3> writeback參數
    優勢:減小出錯機率,且讓對象的持久化更加透明
    缺點:增長額外的內存消耗和時間浪費
    默認狀況下不會記錄持久化對象的修改,以下f1
    須要修改默認參數,不然對象的修改不會保存,以下f2

import shelve

f = shelve.open('shelve_file')
f['key'] = {'int':10,'float':9.5,'string':'Sample data'}    # 直接對文件句柄操做,就能夠存入數據
f.close()

# 不設置writeback參數
f1 = shelve.open('shelve_file')
print(f1['key'])    # {'int': 10, 'float': 9.5, 'string': 'Sample data'}
f1['key']['new_value'] = 'this was not here before'
print(f1['key'])    # {'int': 10, 'float': 9.5, 'string': 'Sample data'}
f1.close()

# 設置writeback參數
f2 = shelve.open('shelve_file',writeback=True)
print(f2['key'])    # {'int': 10, 'float': 9.5, 'string': 'Sample data'}
f2['key']['new_value'] = 'this was not here before'
print(f2['key'])    # {'int': 10, 'float': 9.5, 'string': 'Sample data', 'new_value': 'this was not here before'}
f2.close()
View Code
相關文章
相關標籤/搜索