赞
踩
为什么要序列化
内存中的字典、列表、集合以及各种对象,如何保存到一个文件中。
设计一套协议,按照某种规则,把内存中的数据保存到文件中,文件是一个个字节序列。所以必须把数据额转换为字节序列,输出到文件,这就是序列化,反之,从文件的字节 序列恢复到内存中,就是反序列化。
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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。