python序列化反序列化_Python进阶6---序列化与反序列化

序列化与反序列化***

为什么要序列化 ?

定义

pickle库

#序列化实例

importpickle

lst= 'a b c'.split()

with open('test.txt','wb+')as f:

pickle.dump(lst,f)

file= 'test.txt'with open(file,'wb')as f:

s1= 99s2= 'abc's3= ['a','b',['c','d']]

pickle.dump(s1,f)

pickle.dump(s2,f)

pickle.dump(s3,f)

with open(file,'rb') as f:

s=[]for i in range(3):

s.append(pickle.load(f))print(s)

#对象序列化1

importpickleclassAA:

ttt= 'ABC'

defshow(self):print('abc')

a1=AA()

sr=pickle.dumps(a1)print('sr={}'.format(sr))#AA

a2=pickle.loads(sr)print(a2.ttt)

a2.show()#上面的例子中,其实就保存了一个类名,因为所有的其他东西都是类定义的东西,是不变的,#所以序列化只序列化了一个AA类名。反序列化的时候找到类就可以恢复一个对象。

#对象序列化2

importpickleclassAAA:def __init__(self):

self.tttt= 'abc'b1=AAA()

sr=pickle.dumps(b1)print('sr={}'.format(sr)) #AAA

b2=pickle.loads(sr)print(b2.tttt)#可以看出这回保存了AAA,tttt和abc,因为这才是每一个对象每次都变化的。但是,反序列化的时候要找到AAA类的定义,才能成功。否则会就会抛出异常。#可以这样理解:反序列化的时候,类是模子,二进制序列就是铁水。

应用

本地序列化的情况,情况较少。

一般来说,大多数情况都应用在网络中。将数据序列化后通过网络传输到远程节点,远程服务器上的服务将接收到的数据反序列化后,就可以使用了。

但是,要注意一点,远程接收端,反序列化时必须有对应的数据类型,否则就会报错。尤其是自定义类,必须远程得有。

#实验

importpickleclassAAA:def __init__(self):

self.tttt= 'abc'aaa=AAA()

sr=pickle.dumps(aaa)print(sr)print(len(sr))

file= 'text.txt'with open(file,'wb')as f:

pickle.dump(aaa,f)#将生产的序列化发送到其他节点运行

with open('text1.txt','rb')as f:

a= pickle.load(f)

#解决办法

'''现在,大多数项目,都不是单机的,也不是单服务的。需要通过网络将数据传送到其他节点上去,这就需要大量的

序列化、反序列化。但是,问题是,Python程序之间还可以都是用pickle解决序列化、反序列化,如果是跨平台、

跨语言、跨协议pickle就不太合适了,就需要公共的协议。例如XML、Json、Protocol Buffer等。

不同协议,效率不同,学习曲线不同,适用不同场景,要根据不同的情况分析选型。'''

Json

Json的数据类型

实例

{"person": [

{"name": "tom","age": 18},

{"name": "cy","age": "23"}

],"total": 2}

json模块

Python与Json

Python支持少量内建数据类型到Json类型的转换

常用方法

dumps json编码

dump json编码并存入文件

loads json解码

load dump解码,从文件读取数据

importjson

d= {'name':'chengyu','age':20,'interest':['music','movie']}

j= json.dumps(d)#传入一个对象,return JSONEncoder

print(j)

d1=json.loads(j)print(d1)

注意:一般json编码的数据很少落地,数据都是通过网络传输。传输的时候,要考虑压缩它。

本质上来说它就是个文本,就是个字符串。json很简单,几乎所有语言编程都支持json,因而应用范围很广。

MessagePack(第三方库)

安装

pip install msgpack-python

常用方法

#示例:

importmsgpackimportjson

d={'person':[{'name':'tom','age':18},{'name':'cheng','age':23}],'total':2}

a=json.dumps(d)print("json格式:{},{}".format(len(a),a))

b=msgpack.packb(d)print("magpack格式:{},{}".format(len(b),b))

d1=msgpack.unpackb(b)print(d1)

d1= msgpack.unpackb(b,encoding='utf-8')print(d1)

注意:MessagePack简单易用,高效压缩,支持语言丰富。所以,用它序列化也是一个不错的选择。

作页:

argparse模块

参数分类

基本解析

先来一段最简单的程序

importargparse

parser= argparse.ArgumentParser() #获得一个参数解析器

args = parser.parse_args() #分析参数

parser.print_help() #打印帮助

#运行结果#python test.py -h

usage:test.py [-h]

optional arguments:-h, --help show this help message and exit

argparse不仅仅做了参数的定义和解析,还自动帮助生成了帮助信息。尤其是usage,可以看到现在定义的参数是不是自己想要的

参数解析器ArgumentParser的参数

位置参数解析

importargparse

parser= argparse.ArgumentParser(prog='ls',add_help=True,description='list directory contents') #获得一个参数解析器

parser.add_argument('path')#位置参数

args= parser.parse_args() #分析参数

parser.print_help() #打印帮助

print('*'*10,args)#运行结果:

'''usage: ls [-h] path

ls: error: the following arguments are required: path

'''

'''

程序等定义为:

ls [-h] path

-h为帮助,可有可无

path为位置参数,必须提供'''

传参

importargparse

parser= argparse.ArgumentParser(prog='ls',add_help=True,description='list directory contents') #获得一个参数解析器

parser.add_argument('path')#位置参数

args= parser.parse_args(('/etc',)) #分析参数,同时传入可迭代的参数

parser.print_help() #打印帮助

print('*'*3,args) #打印名词空间中收集的参数#运行结果:

'''usage: ls [-h] path

list directory contents

positional arguments:

path

optional arguments:

-h, --help show this help message and exit

*** Namespace(path='/etc')'''

#注意:Namespace(path='/etc')里面的path可以通过Namespace对象访问,例如args.path

非必须位置参数

#改进1

importargparse#获取一个参数解析器

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list directory contents')

parser.add_argument('path',nargs='?',default='.',help='path help')#位置参数,可有可无,缺省值,帮助

args= parser.parse_args()#分析参数,同时传入可迭代的参数

print(args) #打印名词空间中收集的参数

parser.print_help()#打印帮助

'''#运行结果

Namespace(path='path')

usage: ls [-h] [path]

list directory contents

positional arguments:

path path help

optional arguments:

-h, --help show this help message and exit'''

选项参数

-l的实现

-a的实现

#改进2

importargparse#获取一个参数解析器

parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list directory contents')

parser.add_argument('path',nargs='?',default='.',help='path help')#位置参数,可有可无,缺省值,帮助

parser.add_argument('-l',action='store_true',help='use a long 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='path')

usage: ls [-h] [-l] [-a] [path]

list directory contents

positional arguments:

path path help

optional arguments:

-h, --help show this help message and exit

-l use a long listing format

-a, --all show all files,do not ignore entries starting with .'''

#parser.parse_args('-l -a /tmp'.split())语句的运行结果如下:#Namespace(all=True, l=True, path='/tmp')

ls业务功能的实现

1 #最终版

2 importargparse3 from pathlib importPath4 from datetime importdatetime5 importstat6

7 #print(args)#d打印名词空间中收集的参数

8 #parser.print_help()#打印帮助

9

10 #获取文件类型

11 def_getfiletype(f:Path):12 iff.is_dir():13 return 'd'

14 eliff.is_block_device():15 return 'b'

16 eliff.is_char_device():17 return 'c'

18 eliff.is_socket():19 return 's'

20 eliff.is_symlink():21 return 'l'

22 else:23 return '-'

24

25 modelist = ['r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x']26 def_getmodestr(mode:int):27 m = int(mode) &0o77728 print(mode,m,bin(m))29 mstr =''

30 #for i,v in enumerate(bin(m)[-9:]):

31 #if v == '1':

32 #mstr += modelist[i]

33 #else:

34 #mstr += '-'

35 for i in range(8,-1,-1):36 if m >>i & 1:37 mstr += modelist[8-i]38 else:39 mstr += '-'

40 returnmstr41

42 #目标:-rw-rw-r-- 1 python python 5 Oct 25 00:07 test4

43 #return (mode,st.st_uid,st.st_gid,size,atime,file.name)

44 def list_dir(path,all=False,detail=False,human=False):45

46 #return "{}{}".format(size, units[depth] 即换算后的文件大小

47 units = ['', 'K', 'M', 'G', 'T', 'P'] #' KMGTP'

48 def_gethuman(size: int):49 depth =050 while size >= 1000:51 size = size // 1000

52 depth += 1

53

54 return "{}{}".format(size, units[depth])55

56 #yield (mode,st.st_uid,st.st_gid,size,atime,file.name)

57 def _showdir(path='',all=False,detail=False,human=False):58 '''列出本文件目录'''

59 p =Path(path)60 for file inp.iterdir():61 if not all and str(file.name).startswith('.'):#不显示隐藏文件

62 continue

63 if notdetail:64 yield(file.name,)65 else:66 #mode 硬链接 属主 属组 字节 时间 name

67 st =file.stat()68 #调用内部函数stat.filemode,功能等同于自定义getfiletype函数

69 mode =stat.filemode(st.st_mode)70 size =str(st.st_size)71 ifhuman:72 size =_gethuman(st.st_size)73 atime = datetime.fromtimestamp(st.st_atime).strftime('%Y-%m-%d %H:%M:%S')74 yield(mode,st.st_nlink,st.st_uid,st.st_gid,size,atime,file.name)75

76 yield from sorted(_showdir(args.path,args.all,args.l,args.s),key=lambda x:x[-1])#等同于下面语句

77 #for x in sorted(_showdir(args.path,args.all,args.l,args.human),key=lambda x:x[-1]):

78 #yield x

79 #获取一个参数解析器

80 parser = argparse.ArgumentParser(prog='ls',add_help=True,description='list directory contents')81 parser.add_argument('path',nargs='?',default='.',help='path help')#位置参数,可有可无,缺省值,帮助

82 parser.add_argument('-l',action='store_true',help='use a long listing format')83 parser.add_argument('--all','-a',action='store_true',help='show all files,do not ignore entries')84 parser.add_argument('-s',action='store_true')85

86

87 if __name__ == '__main__':88 args = parser.parse_args() #分析参数,同时传入可迭代的参数

89 parser.print_help()90 print('*'*10,args)91 for st inlist_dir(args.path,args.all,args.s,args.l):92 print(st)

其他的完善

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值