一 什么是 序列化
在我们存储数据或者 网络传输数据的时候,需要对我们的 对象进行处理,把对象处理成方便我们存储和传输的
数据格式,这个过程叫序列化,不同的序列化,结果也不相同,但是目的是一样的,都是为了存储和传输
在 python中存在 三种序列化的 方案
1.pickle,可以将 我们 python 中的 任意数据类型转化成 bytes 并写入到文件中,同样也可以把文件中写好的
bytes 转换成我们 python的 数据,这个过程称为反序列化
pickle 是 python自身独有的 序列化, 目前已知的除了 lambda 以外的任何形式的数据类型都可以
转化
2.shelve 简单另类的一种序列化的方案,有点雷士后面我们学到的 redis ,可以作为一种小型的数据库来使用
3.jsom 将 python 中 常见的字典,列表转化成字符串, 是目前前后端数据 交互使用频率 最高的一种数据格式
json 是可以和 别的语言 互通的 序列
二 pickle
pickle 用起来很简单,就是把我们的 python 对象写入到文件中的一种解决方案,但是写入到文件的是
bytes,所以这东西不是给人看的,是给机器看的
import pickle class Cat: def __init__(self,name,age): self.name = name self.age = age def catchMouse(self): print(self.name,"抓老鼠") c = Cat("jerry",18) bs = pickle.dumps(c) # 序列化一个对象 print(bs) # 一堆二进制 看不懂 cc = pickle.loads(bs) # 把二进制 反序列化成我们的 对象 print(cc) # <__main__.Cat object at 0x019B4330> cc.catchMouse() # 猫依然是猫 还可以抓老鼠
pickle 中的 dumps 可以序列化一个对象,loads 可以反序列化一个对象,我们使用 dum 还可以直接 将 一个
对象写入到文件中
import pickle class Cat: def __init__(self,name,age): self.name = name self.age = age def catchMouse(self): print(self.name,"抓老鼠") c = Cat("jerry",18) bs = pickle.dumps(c) # 序列化一个对象 print(bs) # 一堆二进制 看不懂 cc = pickle.loads(bs) # 把二进制 反序列化成我们的 对象 print(cc) # <__main__.Cat object at 0x019B4330> cc.catchMouse() # 猫依然是猫 还可以抓老鼠 # f = open ("cat",mode = "wb") # pickle.dump(c,f) # 写入到文件中 # f.close() f = open("cat",mode = "rb") pickle.load(f) # 从文件中读出来 cc.catchMouse()
pickle 还可以支持多个对象的 写出
import pickle class Cat: def __init__(self,name,age): self.name = name self.age = age def catchMouse(self): print(self.name,"抓老鼠") lst = [Cat("jerry",19),Cat("tommy",29),Cat("alpha",25)] # f = open("cat",mode = 'wb') # for el in lst: # pickle.dump(el,f) # 写入到文件中 # f.close() f = open("cat",mode = "rb") for i in range(len(lst)): cc = pickle.load(f) # 从文件中 读取对象 cc.catchMouse() #jerry 抓老鼠 # tommy 抓老鼠 # alpha 抓老鼠
但是这样 写 并不好,因为读 的时候,并不知道有多少对象要读,这里记住,不能一行一行的 读,
那真的 要写入或者 读取 多个内容怎么办????????????
很简单,装 list 里, 然后 读取和 写入 都用 list
import pickle class Cat: def __init__(self,name,age): self.name = name self.age = age def catchMouse(self): print(self.name,"抓老鼠") lst = [Cat("jerry", 19), Cat("tommy", 29), Cat("alpha", 25)] f = open("cat",mode="wb") pickle.dump(lst,f) f = open("cat",mode = "rb") li = pickle.load(f) for el in li: el.catchMouse()
记住一点,pickle 序列化的 内容是 二进制的内容(bytes), 不是给人看的,是给机器看的
三 shelve
shelve 提供 python 的 持久化操作,什么叫 持久化操作呢??就是把数据写到 硬盘上,在操作shelve的
时候非常的像 操作一个 字典,这东西到后期,就像 redis 差不多
import shelve shelf = shelve.open("sylar") shelf["jay"] = "哈哈哥" print(shelf["jay"]) shelf.close() # 结果 : 哈哈哥
# 它 和字典差不多,只不过你的字典是一个 文件,接下来,我们存储一些复杂的数据
import shelve s = shelve.open("sylar") s["jay"] = {"name":"哈哈哥","age":18,"hobby":"打游戏"} print(s["jay"]) s.close() # {'name': '哈哈哥', 'age': 18, 'hobby': '打游戏'}
############# 可以做到,但是这里边 有坑
import shelve
s = shelve.open("sylar")
s["jay"]["name"] = "嘻嘻姐" # 尝试改变字典的数据
s.close()
s = shelve.open("sylar")
print(s["jay"]) # 并没有 改变
s.close()
# {'name': '哈哈哥', 'age': 18, 'hobby': '打游戏'}
########## 这个要怎么解决啊
import shelve
s = shelve.open("sylar",writeback = True)
s["jay"]["name"] = "嘻嘻姐" # 尝试改变字典的数据
s.close()
s = shelve.open("sylar")
print(s["jay"]) # 改变了
s.close()
# {'name': '嘻嘻姐', 'age': 18, 'hobby': '打游戏'}
# writeback = True 可以动态的把我们 修改的信息 写入到 文件中,
# 而且这个 鬼东西还可以删除数据,就像字典一样,来看一下::::::::::::
import shelve
# f = shelve.open("sylar",writeback = True)
# del f["jay"]
# f.close()
#
#
# s = shelve.open("sylar",writeback = True)
# print(s["jay"]) # 报错,没有了
# f.close()
s = shelve.open("sylar",writeback = True)
s["jay"] = "张曼玉"
s["zy"] = "朱茵"
s.close()
s = shelve.open("sylar",writeback = True)
for k in s:
print(k) # jay zy
print(s.keys()) # KeysView(<shelve.DbfilenameShelf object at 0x016F7830>)
for k in s.keys():
print(k) # jay zy
for k,v in s.items():
print(k,v) # jay 张曼玉 zy 朱茵
s.close()
综上 shelve 就当成字典用 就行了,它比 redis 还简单
四 json
json是我们 前后端 交互的枢纽,相当于编程界的普通话,大家沟通都用 json,为什么这样呢? 因为 json 的
语法格式可以 完美的表示出一个 对象,那什么是 json 呢,json全称 javascript object notation 翻译过来就是
js 对象简谱,
wf = { "name":"汪峰", "age":18, "hobby":"穿皮裤", "wife":{ "name":"章子怡", "age":17, "hobby":["唱歌","演员","导师"] } }
这个不是字典嘛?对的,在 python中 这玩意叫字典,在 javasript 里 这东西叫 json,一模一样,我们 发现用这样的
数据结构可以完美的表示出任何对象,并且可以完整的 把对象 表示出来,只要代码格式比较好,那可读性也是很
强的,所以大家公认用这样的 一种数据结构 作为 数据交互的格式,
我们的程序是在 python 中写的,但是在前端 是在 JS 那边来 解析 json 的,所以,我们需要把我们程序产生的
字典转化成 json 格式的 json 串(字符串), 然后网络 传输,那边接收到了 之后,就可以根据自己的需求进行 处理
import json dic = {"a":"张曼玉","b":"朱茵","c":"邱淑贞"} s = json.dumps(dic) print(s) # {"a": "u5f20u66fcu7389", "b": "u6731u8335", "c": "u90b1u6dd1u8d1e"}
哇哈哈,成功把 字典处理成 字符串形式,那么怎么解析回来呢?
在 dumps 的时候 给出另外一个参数,ensure_ascii = False 就可以了
import json dic = {"a":"张曼玉","b":"张敏","c":"梅艳芳"} s = json.dumps(dic,ensure_ascii=False) print(s) # {"a": "张曼玉", "b": "张敏", "c": "梅艳芳"}
搞定了,接下来,前端给你传递信息了,你要把前端传递来的 json 字符串转化成 字典
import json s = '{"a":"哈哈哥","b":"嘻嘻姐","c":"呵呵妹"}' dic = json.loads(s) print(type(dic),dic) # <class 'dict'> {'a': '哈哈哥', 'b': '嘻嘻姐', 'c': '呵呵妹'}
是不是很简单啊? 哪里简单了??看不出来啊,哈哈哈
其实 json 也可以 像 pickle 一样 把序列化的 结果写入到 文件中
import json dic = '{"a":"哈哈哥","b":"嘻嘻姐","c":"呵呵妹"}' f = open("tese_json",mode="w",encoding="utf-8") json.dump(dic,f,ensure_ascii=False) f.close()
同样 也可以从文件 中 读取一个 json
import json f = open("tese_json",mode="r",encoding="utf-8") dic = json.load(f) f.close() print(dic) # {"a":"哈哈哥","b":"嘻嘻姐","c":"呵呵妹"}
注意:我们 可以向 同一个 文件写入 多个 json串,但是 读不行
import json lst = [{"a":1},{"b":2},{"c":3}] f = open("tese_json",mode="w",encoding="utf-8") for el in lst: json.dump(el,f) f.close() # 在 tese_json 文件中 存的是 {"a": 1}{"b": 2}{"c": 3} # 注意,此时文件中 的 内容是一行 内容
这在读取的时候 是无法 正常读取的,那如何解决呢? 两套方案:
方案一: 把所有的内容准备好 统一进行写入和读取
缺点: 数据量小还好,数据量大的话,就不够友好了
方案二: 不用 dump,改成 dumps 和 loads ,对每一行 分别 进行 处理
import json # 写入 lst = [{"a":1},{"b":2},{"c":3}] f = open("tese_json",mode="w",encoding="utf-8") for el in lst: s = json.dumps(el,ensure_ascii=True) + " " f.write(s) f.close() # 读取 f = open("tese_json",mode='r',encoding="utf-8") for line in f: dic = json.loads(line.strip()) print(type(dic),dic) f.close() #<class 'dict'> {'a': 1} # <class 'dict'> {'b': 2} # <class 'dict'> {'c': 3}
五 configparser 模块
该模块 适用于 配置文件的格式 与 Windows ini 文件类似,可以包含一个 或者 多个 (section) 每个字节
可以有 多个参考(键 = 值) ,首先,我们看一下 xxx 服务器 的配置文件
基本使用
-
python配置文件模块ConfigParser教程 ...
-
configParser 基本使用 -read(filename) 直接读取文件内容
-
-sections() 得到所有的section,并以列表的形式返回
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [[ bitbucket.org]]User = hg [[ topsecret.server.com]] Port = 50022 ForwardX11 = no
我们用 configparser 就可以 对这样的文件进行 处理,首先,是初始化
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [[ bitbucket.org]] User = hg [[ topsecret.server.com]] Port = 50022 ForwardX11 = no import configparser comfig = configparser.ConfigParser() config["DEFAULT"] = { "sleep":1000, "session-time-out":30, "user-alive":999999 } config["TEST-DB"] = { "db_ip":"192.168.17.189" "port":"3306", "u_name":"root", "u_pwd":"123456" } config["168-DB"]={ "db_ip":"152.163.18.168", "port":"3306", "u_name":"root" "u_pwd":"123456" } config['173-DB'] = { "db_ip": "152.163.18.173", "port": "3306", "u_name": "root", "u_pwd": "123456" } f = open("db.ini",mode="w") config.write(f) # 写入文件 f.flush() f.close()
读取文件信息:
config = configparser.ConfigParser() config.read("db.ini") # 读取⽂文件 print(config.sections()) # 获取到section. 章节...DEFAULT是给每个章节都配备的信息 print(config.get("DEFAULT", "SESSION-TIME-OUT")) # 从xxx章节中读取到xxx信息 # 也可以像字典一样操作 print(config["TEST-DB"]['DB_IP']) print(config["173-DB"]["db_ip"]) for k in config['168-DB']: print(k) for k, v in config["168-DB"].items(): print(k, v) print(config.options('168-DB')) # 同for循环,找到'168-DB'下所有键 print(config.items('168-DB')) #找到'168-DB'下所有键值对 print(config.get('168-DB','db_ip')) # 152.163.18.168 get方法Section下的 key对应的value
增删改操作
# 先读取. 然后修改. 最后写回文件 config = configparser.ConfigParser() config.read("db.ini") # 读取⽂文件 # 添加⼀一个章节 # config.add_section("189-DB") # config["189-DB"] = { # "db_ip": "167.76.22.189", # "port": "3306", # "u_name": "root", # "u_pwd": "123456" # } # 修改信息 config.set("168-DB", "db_ip", "10.10.10.168") # 删除章节 config.remove_section("173-DB") # 删除元素信息 config.remove_option("168-DB", "u_name") # 写回文件 config.write(open("db.ini", mode="w"))