主要内容:
  一. 序列化概述
  二. pickle模块
  三. shelve模块
  四. json模块(重点!)
  五. configpaser模块 一. 序列化概述
1. 序列化: 将字典,列表等内容转换成一个字符串的过程就叫做序列化. 2. 为什么要把其他数据类型转换成字符串?
(1)能够在网络上传输的只能是bytes
(2)能够存储在文件里的只有bytes和str 3. 序列化的目的:
(1)以某种存储形式使自定义对象持久化
(2)将对象从一个地方传递到另一个地方
(3)使程序更具维护性
4. 反序列化:
序列化: str --> 数据结构
反序列化: str <-- 数据结构 5. 在Python中序列化的三种方案:
(1)pickle模块: 可以将Python中的任意数据类型转换成bytes并写入到文件中,同样也可以把文件中写好的bytes转换回Python的数据,这个过程被称为反序列化.
(2)shelve模块: 它是一种简单另类的序列化方案,有一点类似于今后会学习的redis.它可以作为一种小型的数据库来使用.
(3)json模块: 将python中常用的字典,列表转化成字符串.它是目前前后端数据交互使用频率最高的一种数据格式. 二. pickle模块
pickle是把python对象写入到文件中的一种解决方案.写入到文件中的是bytes,它不是给人看的,只有机器可以识别.
pickle可以把python中任意的数据类型序列化. 1. pickle模块中的dumps()方法和loads()方法
注意: dumps()和loads()与文件操作无关 举例说明:
import pickle   # 引入模块
class Cat: # 创建类
def __init__(self, name, age):
self.name = name
self.age = age
def catch_mouse(self):
print(self.name, "抓老鼠") cat = Cat("jerry", 18) # 创建一个对象 byte = pickle.dumps(cat) # dumps()方法 --> 序列化一个对象
print(byte) # 打印结果是一堆很长的二进制字符串 new_cat = pickle.loads(byte) # 把二进制字符串反序列化为原来的对象
new_cat.catch_mouse() # 执行结果: jerry 抓老鼠 --> 反序列化之后得到的对象还是原来那个类型的对象
2. pickle模块中的dump()方法和load()方法
注意: dump()方法和load()方法多用于文件的写入\写出操作 举例说明:
import pickle
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
def catch_mouse(self):
print(self.name, "抓老鼠") cat = Cat("jerry", 18) # 创建一个对象 with open("cat", mode="wb") as f:
pickle.dump(cat, f) # 把对象cat以二进制字符串的形式写进文件中 with open("cat", mode="rb") as f:
new_cat = pickle.load(f) # 从文件中读取信息,并把信息反序列化为对象
new_cat.catch_mouse() # 对象可以访问类中的方法
3. pickle模块还支持多个对象的写入\写出

举例说明:
import pickle
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
def catch_mouse(self):
print(self.name, "抓老鼠") lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("kendy", 21)] with open("cat", mode="wb") as f:
for el in lst:
pickle.dump(el, f) # 把对象序列化并写入文件 with open("cat", mode="rb") as f:
for i in range(len(lst)): # 我们可能事先不知道列表中到底有多少个对象
new_cat = pickle.load(f) # 把文件中的二进制反序列化为对象
new_cat.catch_mouse() # 对象访问catch_mouse()方法
以上操作是有问题的,因为我们在实际情况中是不知道文件内容中有多少个对象的.因此,我们需要换一种操作方式.

举例说明1:
import pickle
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
def catch_mouse(self):
print(self.name, "抓老鼠") lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("cendy", 21)] with open("cat", mode="wb") as f:
pickle.dump(lst, f) # 直接把整个列表序列化并写进文件中 with open("cat", mode="rb") as f:
new_lst = pickle.load(f) # 读取文件中的信息,并将其反序列化,拿到一个列表
for el in new_lst: # 遍历整个列表
el.catch_mouse() # 每一个元素都可以访问catch_mouse()方法
举例说明2:
import pickle
dic1 = {(1, 2, 3):{'a', 'b'}, 1:'abc'}
dic2 = {(1, 2, 3):{'a', 'b'}, 2:'abc'}
dic3 = {(1, 2, 3):{'a', 'b'}, 3:'abc'}
dic4 = {(1, 2, 3):{'a', 'b'}, 4:'abc'}
with open ("pickle_file", "wb") as f:
pickle.dump(dic1, f)
pickle.dump(dic2, f)
pickle.dump(dic3, f)
pickle.dump(dic4, f) # 第一种读取方式:
with open("pickle_file", "rb") as f:
ret = pickle.load(f)
print(ret, type(ret))
ret = pickle.load(f)
print(ret, type(ret))
ret = pickle.load(f)
print(ret, type(ret))
ret = pickle.load(f)
print(ret, type(ret))
# ret = pickle.load(f) # EOFError: Ran out of input
# print(ret, type(ret)) # 如果文件中的对象已经全部被load(拿出来反序列化)了,此时再次load就会报错 # 以上代码执行结果:
# {(1, 2, 3): {'b', 'a'}, 1: 'abc'} <class 'dict'>
# {(1, 2, 3): {'b', 'a'}, 2: 'abc'} <class 'dict'>
# {(1, 2, 3): {'b', 'a'}, 3: 'abc'} <class 'dict'>
# {(1, 2, 3): {'b', 'a'}, 4: 'abc'} <class 'dict'> # 改进后的第二种读取方式:
with open("pickle_file", "rb") as f:
while True:
try:
ret = pickle.load(f)
print(ret, type(ret))
except EOFError: # 异常被捕获了
break
对pickle模块的总结:
(1)pickle只能在python中使用,它只支持python这门语言,跨平台性较差.
(2)pickle序列化支持在python中的几乎所有数据类型.
(3)pickle中的dumps方法序列化的结果一定是字节.
(4)在进行文件操作时,需要用rb和wb模式打开文件.
(5)可以dump多个对象到文件中,也可以从文件中load出来多个对象(load次数超过对象个数会报错,注意捕获异常). 三. shelve模块
shelve提供python的持久化操作,即把数据写到硬盘上.
shelve的操作方式与字典非常相似,可以把它看作是"文件的字典式操作". 1. 增加
import shelve
helf = shelve.open("shelve_test1")
# print(shelf["jay"]) # 报错,因为文件中还没有"jay"的信息 shelf["jay"] = "周杰伦" # 执行新增
print(shelf["jay"]) # 打印结果: 周杰伦 --> 新增成功 shelf.close()
2. 修改
import shelve
shelf = shelve.open("shelve_test1")
print(shelf["jay"])
# 像操作字典一样直接进行修改:
shelf["jay"] = {"name": "周杰伦", "age": 18, "hobby": "唱歌"}
print(shelf["jay"])
shelf.close()
# 执行结果:
# 周杰伦
# {'name': '周杰伦', 'age': 18, 'hobby': '唱歌'} 尝试修改{'name': '周杰伦', 'age': 18, 'hobby': '唱歌'}这个字典中的内容:
shelf = shelve.open("shelve_test1")
shelf["jay"]["name"] = "王力宏" # 尝试修改
shelf.close()
shelf = shelve.open("shelve_test1")
print(shelf["jay"]["name"]) # 查看我们修改的内容
shelf.close()
# 打印结果: 周杰伦 --> 修改失败
解决方案如下:
shelf = shelve.open("shelve_test1", writeback=True)
shelf["jay"]["name"] = "王力宏" # 再次尝试修改
shelf.close()
shelf = shelve.open("shelve_test1")
print(shelf["jay"]["name"]) # 查看我们修改的内容
shelf.close()
# 打印结果: 王力宏 --> 修改成功
writeback=True可以动态地把我们修改的信息写入到文件中,而且它还可以删除数据,就像字典一样

3. 删除
shelf = shelve.open("shelve_test1", writeback=True)
del shelf["jay"]
shelf.close()
shelf = shelve.open("shelve_test1")
print(shelf["jay"]) # 打印结果: 报错 --> 因为之前已经把"jay"的数据给删除了
shelf.close()
4. 查找
shelf = shelve.open("shelve_test1", writeback=True)
shelf["乐坛半壁江山"] = "汪峰"
shelf["华仔"] = "刘德华"
shelf["星爷"] = "周星驰"
shelf.close() # 遍历文件拿到所有key
shelf = shelve.open("shelve_test1") for k in shelf:
print(k) # 拿到所有key for k in shelf.keys():
print(k) # 拿到所有key for v in shelf.values():
print(v) # 拿到所有value for k, v in shelf.items():
print(k, v) # 拿到所有key和value shelf.close()

四. json模块
json模块提供了四个功能: 序列化(dumps和dump), 反序列化(loads和load) 如下实例:
import json
dic = {'key': 'value', 'key2': 'value2'} ret = json.dumps(dic) # 序列化
print(dic, type(dic)) # {'key': 'value', 'key2': 'value2'} <class 'dict'>
print(ret, type(ret)) # {"key": "value", "key2": "value2"} <class 'str'> res = json.loads(ret) # 反序列化
print(res, type(res)) # {'key': 'value', 'key2': 'value2'} <class 'dict'>
# json能够序列化的数据有什么特点?观察下面几个示例,分析结果.
# 特点1: 字典的key是整型,经过序列化和反序列化之后变成了字符串类型
# 特点2: 字典的value是元组, 经过序列化和反序列化之后变成了列表类型
dic = {1:[1,2,3], 2:(4,5,'aa')}
ret = json.dumps(dic) # 序列化
print(dic, type(dic)) # {1: [1, 2, 3], 2: (4, 5, 'aa')} <class 'dict'>
print(ret, type(ret)) # {"1": [1, 2, 3], "2": [4, 5, "aa"]} <class 'str'> res = json.loads(ret) # 反序列化
print(res, type(res)) # {'1': [1, 2, 3], '2': [4, 5, 'aa']} <class 'dict'> # 特点3: set集合类型不能被json序列化
# 特点4: 字典的键必须是字符串才能被json序列化
s = {1, 2, "aaa"}
json.dumps(s) # 报错: TypeError: Object of type 'set' is not JSON serializable
json.dumps({(1,2,3):123}) # 报错: TypeError: keys must be a string
总结: json在所有的语言之间都通用:即在python中json序列化后的数据,把它拿到java中也可以反序列化,反之亦然.
可以认为,json序列化后的数据,在其他语言中也能够反序列化回来,所有语言都可以识别"json序列化后的数据".
由此也导致json能够处理的数据非常有限,只有 字符串,列表,字典,数字 这几种类型,而且字典中的key只能是字符串.
# 向文件中写入字典
import json
dic = {'key' : 'value','key2' : 'value2'}
ret = json.dumps(dic) # 序列化(这里是将序列化结果全部写入内存,下面的代码再从内存中读取全部结果并写入文件)
with open("json_file", "a") as f:
f.write(ret) # 从内存中读取数据,并写入文件中 # 从文件中读取字典
with open ("json_file", "r") as f:
str_dic = f.read() # 读取全部文件内容并将其写入内存
dic = json.loads(str_dic) # 将内存中的字符串反序列化
print(dic) # 打印结果: {'key': 'value', 'key2': 'value2'} # dump和load是直接操作文件的,如下示例:
dic = {'key1' : 'value1','key2' : 'value2'}
with open('json_file', 'a') as f:
json.dump(dic, f) # 把dic序列化并写入文件json_file中 with open('json_file', 'r') as f:
dic = json.load(f) # 把文件内容反序列化为字典
print(dic) # {'key1': 'value1', 'key2': 'value2'}
总结: 如果我们是进行文件相关的操作(读/写),那么可以用dump和load.如果是处理网络上传输的数据是,由于此时数据都是在内存中,这就要用到dumps和loads了.
# 特点5: 不支持连续的存取
dic = {'key1':'value1', 'key2':'value2'}
with open("json_file", "a") as f:
json.dump(dic, f)
json.dump(dic, f)
json.dump(dic, f) with open("json_file", "r") as f:
dic = json.load(f)
print(dic.keys())
总结: 上面程序中虽然成功通过dump多次向文件中存入3个字典,但是load会报错. 也就是说load只能读取"存一个字典"的文件,嵌套字典也可以,但最外层只能是一个.
# 解决办法
dic = {'key1':'value1', 'key2':'value2'}
with open("json_file", "a") as f:
str_dic = json.dumps(dic)
f.write(str_dic + "\n")
str_dic = json.dumps(dic)
f.write(str_dic + "\n")
str_dic = json.dumps(dic)
f.write(str_dic + "\n") with open("json_file", "r") as f:
for line in f:
dic = json.loads(line.strip())
print(dic) # 执行结果:
# {'key1': 'value1', 'key2': 'value2'}
# {'key1': 'value1', 'key2': 'value2'}
# {'key1': 'value1', 'key2': 'value2'}
综上所述:
json的dumps和loads -- 在内存中做数据转换:
dumps(序列化) --> 数据类型 转成 字符串
    loads(反序列化) --> 字符串 转成 数据类型
json的dump和load -- 直接将数据类型写入文件,直接从文件中读出数据类型:
dump(序列化) --> 把数据类型序列化并写入文件
load(反序列化) --> 从文件中读出内容并将其反序列化为数据类型 json是所有语言都通用的一种序列化格式,只支持列表,字典,字符串,数字,并且字典的key必须是字符串.
# ensure_ascii 关键字参数
dic = {"key":"你好}
print(json.dumps(dic)) # {"key": "\u4f60\u597d"}
print(json.dumps(dic, ensure_ascii=False)) # {"key": "你好"}

# json 的格式化输出
data = {"username":["赵日天", "二愣子"], "gender":"male", "age":16}
json_dic = json.dumps(data, sort_keys=True, indent=4, separators=(',',':'), ensure_ascii=False)
print(json_dic)
# 执行结果:
# {
# "age":16,
# "gender":"male",
# "username":[
# "赵日天",
# "二愣子"
# ]
# }

五. configparser模块
该模块适⽤于配置⽂件的格式与windows下的ini⽂件类似,可以包含⼀个或多个节(section),每个节
可以有多个参数(键=值).
import configparser
config = configparser.ConfigParser()
config['DEFAULT'] = {
"sleep": 1000,
"session_time_out": 30,
"user_alive": 999999
}
config['TEST-DB'] = {
"db_ip": "192.168.17.189",
"port": "",
"u_name": "root",
"u_pwd": ""
}
config['168-DB'] = {
"db_ip": "152.163.18.168",
"port": "",
"u_name": "root",
"u_pwd": ""
}
config['173-DB'] = {
"db_ip": "152.163.18.173",
"port": "",
"u_name": "root",
"u_pwd": ""
}
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": "",
"u_name": "root",
"u_pwd": ""
}
# 修改信息
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"))
												

最新文章

  1. 国内最全最详细的hadoop2.2.0集群的MapReduce的最简单配置
  2. @property语句
  3. POJ 2186 Popular Cows --强连通分量
  4. Apache2.2+php5.4在windows上配置实例
  5. 两个结构体ifconf和ifreq
  6. Gulp-livereload:实时刷新编码
  7. CSS 规避脱标之两种用法
  8. FineReport中如何对cpt模板加密
  9. 一、Hadoop学习笔记————概述
  10. 小实例---关于input宽度自适应以及多个input框合并拆分
  11. hdu 2825 aC自动机+状压dp
  12. springboot2.x里面访问静态资源的坑
  13. 点击a标签实现txt文件另存的效果
  14. python 彩色日志配置
  15. python语法_字符类型
  16. ModelAttribue注解的使用
  17. jQuery~DOM基础操作
  18. Docker Compose practice
  19. Entity Framework实现事务回滚
  20. Educational Codeforces Round 11 B. Seating On Bus 水题

热门文章

  1. 内网监控zabbix
  2. osm3ge
  3. django + ckeditor + 七牛云,图片上传到七牛云
  4. Acwing-286-选课(树上DP)
  5. docker自定义镜像仓库
  6. 51 Nod 1191消灭兔子
  7. 【线性代数】1-0:向量(Vector)
  8. 下载使用IDE练习插件
  9. .NetCore 读取配置文件
  10. maven创建可执行jar包项目的配置