python---序列化小结
1 什么叫序列化
在我们存储数据或网络传输数据时候,需要多我们对象进行处理,把对象处理成方便储存和网络传输的数据格式,这个过程叫做序列化
2 对象序列化有三种方式;
2.1 pickle 可以将python中任意数据类型转换成bytes并写入文件中,同样可以把文件中写好的bytes转化成python的相对应的数据,这个过程称为反序列化;
import pickle
# 可以将对象写入文件中
#基本用法
#pickle.dump(obj,file,protocol=None,*,fix_imports=True)可以写入到文本中
#pickle.dump(obj,protocol=None,* fix_import=True) 一般用于正常的操作
# pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict") 可以从文本加载
# pickle.loads(s, *, fix_imports=True, encoding="ASCII", errors="strict") 一般用于正常的操作
举例说明:
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age=age
def login(self):
pass
李明 = Person('李明',20)
王汪 = Person('王汪',19)
孙艳 = Person('孙艳',18)
# S1 = pickle.dumps(李明) # 序列化一个对象,将对象转换成bytes的形式
# S2 = pickle.loads(S1) # 进行反序列化,将bytes转换对象
li = [李明,王汪,孙艳]
with open('user',mode='ab') as f:
pickle.dump(li, f) # 把列表转化butes,写入文件
with open('user',mode='rb') as f:
li= pickle.load(f) # 从文本中读取,将bytes的形式转化为列表
print(li)
for i in li:
print(i)
简单注册和登录的例子:
class Account:
def __init__(self,name,pwd):
self.name=name
self.pwd=pwd
def login():
username=input('请输入用户:').strip()
userpwd=input('请输入密码:').strip()
with open('usernamelist',mode='rb') as f:
while True:
try:
Account_User=pickle.load(f)
if username==Account_User.name and userpwd==Account_User.pwd:
print('登录成功')
return True
except:
print('输入用户名和密码不对')
return False
def regiest():
while True:
username=input("请输入用户名:").strip()
with open('usernamelist',mode='rb') as f:
while True:
try:
Account_User=pickle.load(f)
except: EOFError
if username==Account_User.name:
print('用户名已存在,请重新选择用户名')
break
else:
while True:
userpwd=input("请输入用户密码:").strip()
userpwd2=input('请再次输入密码:').strip()
if userpwd==userpwd2:
Account_User=Account(username,userpwd)
with open('usernamelist',mode='ab') as f:
pickle.dump(Account_User,f)
return True
else:
print('二次密码输入不一致,请重试输入秘密')
def run():
while 1:
opt_lst=[('登录', 'login'), ('注册', 'regiest'), ('退出', 'exit')]
for index,lst in enumerate(opt_lst,1):
print(lst[0],index)
try:
num=int(input('请输入对应序号:').strip())
except: EOFError
if hasattr(opt_lst[num-1][1],opt_lst[num - 1][1]):
getattr(opt_lst[num-1][1],opt_lst[num-1][1])()
if num==1: login()
elif num==2: regiest()
else: break
# print(opt_lst[num-1][1])
# # if hasattr(opt_lst[num-1][1],opt_lst[num-1][1]):
# getattr(opt_lst[num-1][1],opt_lst[num-1][1])()
if __name__=='__main__':
run()
2.2 shelve 简单另类一种序列化方法,可以作为小型数据库使用
2.3 json 将python中常见的字典,列表转换字符,是目前前后端数据交换使用频率最高一种数据格式
import json
# json.dumps()
# 把字典转换成json字符串
# json.loads()
# 把json字符串转化成字典
# json.dump()
# 把字典转换成json字符串.写入到文件
# json.load()
# 把文件中的json字符串读取.转化成字典
dic = {'输出':'鲁班','坦克':'项羽','法师':'安琪拉了'}
gg = json.dumps(dic,ensure_ascii=False) #ensure_ascii=False,是能够看到中文
print(gg)#{"输出": "鲁班", "坦克": "项羽", "法师": "安琪拉了"}
print(type(gg))#<class 'str'>
bb = '{"输出": "鲁班", "坦克": "项羽", "法师": "安琪拉"}'
gg = json.loads(bb)
print(gg)#{'输出': '鲁班', '坦克': '项羽', '法师': '安琪拉'}
print(type(gg))#<class 'dict'>
gg = json.dump(dic,open('json.data','w',encoding='utf-8'),indent=4,ensure_ascii=False)
print(gg)#None # ensure_ascii=False 保存到文件的时候不使用ascii 编码
print(type(gg))#<class 'NoneType'>
dd = json.load(open('json.data','r',encoding='utf-8'))
print(type(dd))#<class 'dict'>
print(dd)#{'输出': '鲁班', '坦克': '项羽', '法师': '安琪拉了'
#将一个类的属性保存到json中
class Person:
def __init__(self,name,func):
self.name = name
self.func = func
# ensure_ascii=True 保存到文件的时候不使用ascii 编码
a = Person('鲁班','射手')
# 方案1,通过类的特殊方法
dd = json.dumps(a.__dict__,ensure_ascii=False)
print(dd)
# 方案2,通过自己建立转换模板
def gg(obj):
print('哈哈')
return {'kk':obj.name,'fn':obj.func}#
hh = json.dumps(a,default=gg,ensure_ascii=False) #{"kk": "鲁班", "fn": "射手"}
print(hh)
# 将jsonz字符串转换为对象
def gg(dic):
return Person(dic['kk'],dic['fn'])
a = '{"kk": "鲁班", "fn": "射手"}'
print(json.loads(a,object_hook=gg))
hh = json.loads(a,object_hook=gg)
print(hh.name)
default = 把对象转化成字典. 需要自己写转换过程 object_hook = 把字典转化成对象. 需要自己写转换过程