python中常用的序列化模块_Python中的序列化和反序列化
為什么要序列化
內存中的字典、列表、集合以及各種對象,如何保存到一個文件中。
設計一套協議,按照某種規則,把內存中的數據保存到文件中,文件是一個個字節序列。所以必須把數據額轉換為字節序列,輸出到文件,這就是序列化,反之,從文件的字節 序列恢復到內存中,就是反序列化。
1、定義
Serialization系列化,將內存中對象存儲下來,把他變成一個個字節。二進制。
deSerialization反序列化,將文件的一個個字節到內存中。
序列胡保存到文件就是持久化。
可將數據序列化后持久化,或者網絡傳輸,也可以將文件中或者網絡接受到的字節序列反序列化。
2、pickle庫
Python中的序列化、反序列化模塊
dumps對象序列化為bytes對象
dump對象序列化到文件對象,就是存入到文件。
loads從bytes對象反序列化。
load對象反序列化,從文件讀取數據.
##
import pickle
filename = 'ser'
x= 'a'
y = '100'
z = '100'
with open(filename,'wb') as f:
pickle.dump(x,f)
pickle.dump(y,f)
pickle.dump(z,f)
with open(filename,'rb')as f:
for _ in range(3):
a = pickle.load(f)
print(a,type(a))
還原的時候不一定是完全一樣的。
序列化應用:一般來說,本地序列化的情況,應用較少,大多數都是用在網絡傳輸上面的。
將數據序列化后通過網絡傳輸到遠程節點,遠程服務器上的服務將接受到的數據反序列化后,就可以使用了。
但是,要注意的是,遠程接收端,反序列化時候必須有對應的數據類型,否則就會報錯。尤其是自己定義的類。必須遠程得有一致的定義。
3、Json
1)是一種輕量級的數據交換格式,基于ECMAScript(w3c制定的JS規范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數據。
2)數據類型
值
雙引號引起來的字符串,數值,true和flase,null,對象,數組,這些都是值。
字符串
由雙引號包圍起來的任意字符的組合,可以有轉義字符。
數值:有正負,整數,浮點數。
對象:無序的鍵值對的集合。
格式:{key1:value1,.....keyn:valuen}
Key必須是一個字符串,需要雙引號包圍這個字符。
Value可以是任意合法的值。
數組:有序的值的集合
格式:[value1,....valuen]
例子:
2) json模塊
Python與json
Python支持少量內建數據類型到json類型的轉換。
Python類型
Json類型
True
True
False
False
None
Null
Str
String
Int
Integer
Float
Float
List
Array
Dict
obiect
3) 常用的方法
Python 類型
Json類型
Dumps
Json編碼
Dump
Json編碼并寫入文件
Loads
Json解碼
Load
Json解碼,從文件讀取數據
import json
d = {'name':'tom','age':20,'interest':['music','movie']}
j = json.dumps(d)
print(j)
d1 = json.loads(j)
print(d1)
{"name": "tom", "age": 20, "interest": ["music", "movie"]}
{'name': 'tom', 'age': 20, 'interest': ['music', 'movie']}
一般json編碼的數據就很少落地,數據都是通過網絡傳輸。傳輸的時候要考慮壓縮。
本質上來說就是一個文本,就是個字符串。
Json很簡單,幾乎語言編程都支持json,所以應用范圍十分廣泛。
4、MessagePack
是一個基于二進制高效的對象化序列類庫,可用于跨語言通信。
可以像json那樣,在許多種需要之間交換結構對象。
比json更快速也更輕巧。
支持python,ruby,java,C/C++等眾多語言。
安裝:
Pip install msgpack-python
常用方法
Packb序列化對象,提供了dumps兼容pickle和json
Unpackb反序列化對象,提供了loads來兼容
Pack序列化對象保存到文件對象,提供了dump來兼容
Unpack反序列化對象保存到文件對象,提供了load來兼容。
##
import json
import msgpack
d = {'person':[{'name':'tom','age':18},{'name':'jerry','age':16}],'total':2}
j = json.dumps(d)
m =msgpack.dumps(d)
print('json={},msgpack={}'.format(len(j),len(m)))
print(j.encode(),len(j.encode()))
print(m)
u = msgpack.unpackb(m)
print(type(u),u)
u = msgpack.unpackb(m,encoding='utf-8')
print(type(u),u)
MessagePack簡單易用,高效壓縮,支持的語言豐富
序列化也是一種很好的選擇。
簡單易用,高效壓縮,支持語言豐富,所以,用它序列化是一種很好的選擇。
6、argparse模塊
1)一個可執行文件或者腳本都可以接收參數。
ls -l/etc /etc是位置參數 -l 是短選項
如何將參數傳遞到程序,就使用參數分析模塊argparse
1) 參數分類。
參數分為:位置參數,參數放在哪里,就要對應一個參數位置,例如/etc 就是對應的一個參數位置。
選項參數,必須通過前面 - 的短選項或者 --的長選項,然后后面的才算是參數,短選項后面也可以沒有參數。
/etc 對應的就是位置參數, -l是選項參數。
3)基本解析
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
parser.print_help()
usage: argparse模塊使用.py [-h]
optional arguments:
-h, --help show this help message and exit
Argparse不僅僅做了參數的定義和解析,還自動生成了幫助信息。Usage,可以看到現在定義的參數是否是自己想要的。
4)解析器的參數
參數名稱
說明
Prog
程序的名字,缺省使用,sys.argv[0]
add_help
自動生成解析器增加 - h和--help選項,默認為True
description
為程序添加功能描述
import argparse
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
args = parser.parse_args()
parser.print_help()
usage: ls [-h]
list directorycontents
optional arguments:
-h, --help show this help message and exit
2) 位置參數解析器
ls 基本功能解決目錄內容的打印。
打印的時候應該制定目錄路徑,需要的位置參數。
import argparse
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path')
args = parser.parse_args() #分析參數
parser.print_help() #打印幫助
usage: ls [-h] path
ls: error: the following arguments are required: path
程序等定義為
ls [-h] path
-h為幫助,可有可無
path 為位置參數,必須提供。
6)傳參
Parse_args(args=None,namespace=None)
args參數列表,一個可迭代對象,內部會把可迭代對象轉換成list,如果為None則使用命令行傳入參數,非None則使用args參數的可迭代對象。
import argparse
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path') #位置參數
args = parser.parse_args(('/etc',)) #分析參數
print(args) #打印名詞空間中收集的參數
parser.print_help() #打印幫助
Namespace(path='/etc')
usage: ls [-h] path
list directorycontents
positional arguments:
path
optional arguments:
-h, --help show this help message and exit
Namespace(path='/etc')里面的path參數存儲在一個Namespace對象內的屬性上,,可以通過Namespace對象屬相來訪問。args.path
7)非必須位置參數。
必須輸入位置參數,否則會報錯。
有些時候ls命令不需要輸入任何路徑就表示列出當前目錄的文件列表。
import argparse
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置參數,可有,可無,缺省值,幫助
args = parser.parse_args() #分析參數
print(args) #打印名詞空間中收集的參數
parser.print_help() #打印幫助
Namespace(path='.')
usage: ls [-h] [path]
list directorycontents
positional arguments:
path path help
optional arguments:
-h, --help show this help message and exit
看到path也變成了可選位置參數,沒有提供默認值.表示當前的路徑。
.help表示幫助文檔中這個參數的描述。
.nargs表示這個參數接受結果參數,?表示可有可無,+表示至少一個,*表示任意個,數字表示必須是制定數目個。
.default表示如果不提供該參數,就一直使用這個值,一般和?、*配合,因為他們都可以不提供位置參數,不提供就是使用缺省值。
8)選項參數
-l 的實現:
-a 的實現。長選項同時給出,
import argparse
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置參數,可有,可無,缺省值,幫助
parser.add_argument('-l',action ='store_true',help = 'use a one listing format')
parser.add_argument('-a','--all',action ='store_true',help='show all files,do not ignore entries starting with .')
args = parser.parse_args() #分析參數
print(args) #打印名詞空間中收集的參數
parser.print_help() #打印幫助
Namespace(all=False, l=False, path='.')
usage: ls [-h] [-l] [-a] [path]
list directorycontents
positional arguments:
path path help
optional arguments:
-h, --help show this help message and exit
-l use a one listing format
-a, --all show all files,do not ignore entries starting with .
1) ls 業務功能的實現。
上面解決了參數的定義和傳參的問題,下面解決業務問題:
(1) .列出所有指定路徑的文件,默認是不遞歸的。
(2) -a顯示所有文件,包括隱藏文件。
(3) -l詳細列表模式顯示。
代碼實現:listdirdetail和listdir
import argparse
from pathlib import Path
from datetime import datetime
#獲得一個參數解析器
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置參數,可有,可無,缺省值,幫助
parser.add_argument('-l',action ='store_true',help = 'use a one listing format')
parser.add_argument('-a','--all',action ='store_true',help='show all files,do not ignore entries starting with .')
args = parser.parse_args() #分析參數
print(args) #打印名詞空間中收集的參數
parser.print_help() #打印幫助
def listdir(path,all=False):
p = Path(path)
for i in p.iterdir():
if not all and i.name.startswith('.'): #不顯示隱藏文件
continue
yield i.name
print(list(listdir(args.path)))
#獲取文件類型
def _getfiletype(f:path):
# f = Path(path)
if f.is_dir():
return 'd'
elif f.is_block_device():
return 'b'
elif f.is_char_device():
return 'c'
elif f.is_socket():
return 's'
elif f.is_symlink():
return 'l'
else:
return '-'
##顯示文件權限等 mode
modelist = dict(zip(range(9),['r','w','x','r','w','x','r','w','x']))
def _getmodestr(mode:int):
m = mode &0o777
mstr = ''
for i in range(8,-1,-1):
if m >>i & 1:
mstr += modelist[8-i]
else:
mstr +='-'
return mstr
def listdirdetail(path,all=False,detail=False):
p = Path(path)
for i in p.iterdir():
if not all and i.name.startswith('.'):
continue
if not detail:
yield (i.name,)
else:
stat = i.stat()
# t = _setfiletype(i)
mode = _getfiletype(i)+_getmodestr(stat.st_mode)
atime = datetime.fromtimestamp(stat.st_atime).strptime('%Y %m %d %H:%M:%S')
yield (mode,stat.st_nlink,stat.st_uid,stat.st_gid,stat.st_size,atime,i.name)
for x in listdir(args.path):
print(x)
Mode是整數,八進制描述的權限,最終顯示rwx的格式。
modelist = dict(zip(range(9),['r','w','x','r','w','x','r','w','x']))
def _getmodestr(mode:int):
m = mode &0o777
mstr = ''
for i
in range(8,-1,-1):
if m
>>i & 1:
mstr += modelist[8-i]
else:
mstr +='-'
return mstr
2)
排序
顯示的文件按照文件名的升序排序輸出。
Sorted(listdir(args.path,detail=True),key=lambda x:x[len(x)-1])
3)
完整代碼:
import argparse
from pathlib import Path
from datetime import datetime
#獲得一個參數解析器
parser = argparse.ArgumentParser(prog= 'ls',add_help=True,description='list directorycontents')
parser.add_argument('path',nargs='?',default='.',help='path help') #位置參數,可有,可無,缺省值,幫助
parser.add_argument('-l',action ='store_true',help = 'use a one listing format')
parser.add_argument('-a','--all',action ='store_true',help='show all files,do not ignore entries starting with .')
def listdir(path,all=False,detail=False):
def _getfiletype(f: path):
if f.is_dir():
return 'd'
elif f.is_block_device():
return 'b'
elif f.is_char_device():
return 'c'
elif f.is_socket():
return 's'
elif f.is_symlink():
return 'l'
else:
return '-'
modelist = dict(zip(range(9), ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']))
def _getmodestr(mode: int):
m = mode & 0o777
mstr = ''
for i in range(8, -1, -1):
if m >> i & 1:
mstr += modelist[8 - i]
else:
mstr += '-'
return mstr
def _listdir(path, all=False, detail=False):
p = Path(path)
for i in p.iterdir():
if not all and i.name.startswith('.'):
continue
if not detail:
yield (i.name,)
else:
stat = i.stat()
# t = _setfiletype(i)
mode = _getfiletype(i) + _getmodestr(stat.st_mode)
atime = datetime.fromtimestamp(stat.st_atime).strptime('%Y %m %d %H:%M:%S')
yield (mode, stat.st_nlink, stat.st_uid, stat.st_gid, stat.st_size, atime, i.name)
yield from sorted(_listdir(path, all, detail), key=lambda x: x[len(x) - 1])
if __name__ == '__main__':
args = parser.parse_args() # 分析參數
print(args) # 打印名詞空間中收集的參數
parser.print_help() # 打印幫助
files = listdir(args.path,args.all,args.l)
4) -h的實現
-h ,-human-readable,如果-l存在,-h有效。
import argparse
from pathlib import Path
from datetime import datetime
parser = argparse.ArgumentParser(prog='ls',description='list directory contents',add_help=False)
parser.add_argument('path',nargs='?',default='.',help='path help')
parser.add_argument('-h','--human-readable',action='store_true',help='with -l,print sizes in human readable format')
# args = parser.parse_args() # 分析參數
# print(args) # 打印名詞空間中收集的參數
# parser.print_help() # 打印幫助
def listdir(path,all=False,detail=False,human=False):
def _getfiletype(f:path):
"""獲取文件的類型"""if f.is_dir():
return 'd'
elif f.is_block_device():
return 'b'
elif f.is_char_device():
return 'c'
elif f.is_socket():
return 's'
elif f.is_symlink():
return 'l'
elif f.is_fifo():
return 'p'
else:
return '-'
modelist = dict(zip(range(9),['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']))
def _getmodest(mode:int):
m =mode & 0o777
mstr = ''
for x in range(8,-1,-1):
if m >> i & 1:
mstr += modelist[8-i]
else:
mstr += '-'
return mstr
def _gethuman(size: int):
units = 'KMGTP'
depth = 0
while size >= 1000:
size = size // 1000
depth += 1
return '{}{}'.format(size, units[depth])
def _listdir(path,all=False,detail=False,human=False):
p =Path(path)
for i in p.iterdir():
if not all and i.name.startswith('.'):
continue
if not detail:
yield (i.name,)
else:
stat = i.stat()
# t = _setfiletype(i)
mode = _getfiletype(i) + _getmodestr(stat.st_mode)
atime = datetime.fromtimestamp(stat.st_atime).strptime('%Y %m %d %H:%M:%S')
yield (mode, stat.st_nlink, stat.st_uid, stat.st_gid, stat.st_size, atime, i.name)
yield from sorted(_listdir(path, all, detail), key=lambda x: x[len(x) - 1])
if __name__ == '__main__':
args = parser.parse_args() # 分析參數
print(args) # 打印名詞空間中收集的參數
parser.print_help() # 打印幫助
files = listdir(args.path,args.all,args.l)
5) 改進mode的模塊
使用stat模塊
import stat
from pathlib import Path
stat.filemode(Path().stat().st_mode)
6) 最終代碼:
import argparse
import stat
from pathlib import Path
from datetime import datetime
parser = argparse.ArgumentParser(prog='ls',description='list directory contents',add_help=False)
parser.add_argument('path',nargs='?',default='.',help='path help')
parser.add_argument('-h','--human-readable',action='store_true',help='with -l,print sizes in human readable format')
parser.add_argument('-l',action ='store_true',help = 'use a one listing format')
parser.add_argument('-a','--all',action ='store_true',help='show all files,do not ignore entries starting with .')
# args = parser.parse_args() # 分析參數
# print(args) # 打印名詞空間中收集的參數
# parser.print_help() # 打印幫助
def listdir(path,all=False,detail=False,human=False):
def _gethuman(size: int):
units = 'KMGTP'
depth = 0
while size >= 1000:
size = size // 1000
depth += 1
return '{}{}'.format(size, units[depth])
def _listdir(path, all=False, detail=False, human=False):
p = Path(path)
for i in p.iterdir():
if not all and i.name.startswith('.'):
continue
if not detail:
yield (i.name,)
else:
st = i.stat()
# t = _setfiletype(i)
mode = stat.filemode(st.st_mode)
atime = datetime.fromtimestamp(st.st_atime).strptime('%Y %m %d %H:%M:%S')
size = str(st.st_size) if not huam else _gethuman(st.st_size)
yield (mode, st.st_nlink, st.st_uid, st.st_gid, size, atime, i.name)
yield from sorted(_listdir(path, all, detail), key=lambda x: x[len(x) - 1])
if __name__ == '__main__':
args = parser.parse_args() # 分析參數
print(args) # 打印名詞空間中收集的參數
parser.print_help() # 打印幫助
files = listdir(args.path, args.all, args.l)
總結
以上是生活随笔為你收集整理的python中常用的序列化模块_Python中的序列化和反序列化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: maven deploy plugin_
- 下一篇: springcloud配置文件上传大小_