Python基础(十六)
今日主要内容
- 内置模块(标准库)
- 序列化
 - hashlib
 - collections
 
 - 软件开发规范
 
一、内置模块(标准库)
(一)序列化模块
- 什么是序列化?
- 将一种数据结构(如列表、字典)转换为另一种特殊的数据结构(如字符串、bytes类型)的过程就是序列化过程
 - 数据传输的过程中,传输的都是字节,现在有一个列表需要传输,我需要将列表转换为字符串,在将字符串进行编码,但对方最终接收到的是一个字符串,字符串是不能原封不动的还原成列表的,这时候就需要用到反序列化将字符串转换回列表
 
 
1.json模块(重要)
json文件相当于编程界的普通话,是各种语言交互的枢纽,当数据需要在多种语言间传输,就必须将数据转换成json字符串,对方将接受到的json字符串再转换成对应语言的数据类型,完美还原
json模块方法介绍:
json.dumps() 将对象序列化 json.loads() 将对象反序列化 json.dump() 将对象序列化写入文件 json.load() 将对象读取后反序列化 dumps、loads:用于网络传输dump、load:用于文件写读
json.dumps()
- 函数定义:
dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) - 函数说明:将对象序列化为json格式的字符串,其余参数中的
ensure_ascii:若对象中出现的非ascii字符(如中文)时会被转换,若显示原字符,指定ensure_ascii=False 
import json print(json.dumps(["张旭东666"]))
print(json.dumps(["张旭东666"], ensure_ascii=False)) 运行结果:
["\u5f20\u65ed\u4e1c666"]
["张旭东666"]
- 函数定义:
 json.loads()
- 函数定义:
loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) - 函数说明:将json格式的字符串反序列化
 
import json print(json.loads("[1,2,3,4]"))
print(type(json.loads("[1,2,3,4]"))) 运行结果:
[1, 2, 3, 4]
<class 'list'>
- 函数定义:
 json.dump()
- 函数定义:
dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) - 函数说明:将对象转换为json流写入到文件(fp为文件句柄)中
 
import json with open("text.txt", "w", encoding="utf-8") as f:
json.dump([1, 2, 3, 4], f)
- 函数定义:
 json.load()
- 函数定义:
load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) - 函数说明:读取文件句柄并将字符串反序列化
 
with open("text.txt", encoding="utf-8") as f:
lst = json.load(f)
print(lst)
print(type(lst)) 运行结果:
[1, 2, 3, 4]
<class 'list'>
- 函数定义:
 
如果向文件中写入多个json串,无法读取,因为在文件中写入的都是一行内容
- 解决方法1:将所有内容准备好了一次性写入和读取
 
import json
lst = [{"k1": 1}, {"k2": 2}, {"k3": 3}] # 准备好放在一起
with open("text.txt", "w+", encoding="utf-8") as f:
json.dump(lst, f) # 一起写入
f.seek(0)
for el in json.load(f): # 一起读取
print(el) 运行结果:
{'k1': 1}
{'k2': 2}
{'k3': 3}
- 解决方法2:改用
dumps和loads对每一行分别进行处理 
import json lst = [{"k1": 1}, {"k2": 2}, {"k3": 3}]
with open("text.txt", "w+", encoding="utf-8") as f:
for el in lst:
f.write(json.dumps(el)+"\n") # 利用write和dumps一行一行序列化写入
f.seek(0)
for line in f:
print(json.loads(line)) # 一行一行读取反序列化 运行结果:
{'k1': 1}
{'k2': 2}
{'k3': 3}
2.pickle模块
pickle模块将所有数据类型和对象序列化转换成bytes类型(不支持lambda匿名函数),还可以反序列化还原回原数据,pickle模块只能在python语言中使用,其他语言不识别
pickle模块支持多行序列化写入和多行读取反序列化功能
pickle模块方法介绍:
pickle.dumps() 将对象序列化 pickle.loads() 将对象反序列化 pickle.dump() 将对象序列化写入文件 pickle.load() 将对象读取后反序列化 dumps、loads:用于网络传输dump、load:用于文件写读- pickle的方法和json完全相同,与json的区别就是pickle序列化后是字节,而json序列化后是字符串
 
3.shelve模块(了解)
- 了解一下就好,这里不做介绍
 
(二)hashlib模块
hashlib模块被人称为加密算法、摘要算法等,它的功能是用来对数据进行加密和文件校验使用,通过模块中的功能函数将数据转换为一个固定长度的字符串
数据转换流程:
- 明文 —— 字节 —— 密文
 
hashlib模块的特点:
- 转换的密文没有规律
 - 操作不可逆
 - 不同的bytes类型数据转换的密文一定不同
 
import hashlib sha1 = hashlib.sha1()
sha1.update("21".encode("utf-8")) # 将21转换为密文
print(sha1.hexdigest()) sha1 = hashlib.sha1()
sha1.update("12".encode("utf-8")) # 将12转换为密文
print(sha1.hexdigest()) 运行结果: # 结果一定不同,且无规律
472b07b9fcf2c2451e8781e944bf5f77cd8457c8
7b52009b64fd0a2a49e6d8a939753077792b0554
- 相同的bytes类型数据转换的密文一定相同
 
import hashlib sha1 = hashlib.sha1()
sha1.update("12".encode("gbk")) # 用gbk进行编码
print(sha1.hexdigest())
sha1 = hashlib.sha1()
sha1.update("12".encode("utf-8")) # 用utf-8进行编码
print(sha1.hexdigest()) 运行结果: # 内容相同,无论编码方式是什么,密文一定相同,
7b52009b64fd0a2a49e6d8a939753077792b0554
7b52009b64fd0a2a49e6d8a939753077792b0554
加密方式:
- md5
 - sha1
 - sha256
 - sha512
 
模块应用一:对数据进行加密
方法介绍:
hashlib.md5() 对应加密方式初始化 obj.update() 向初始化的对象中添加要加密的内容,内容必须是字节码 obj.hexdigest() 对对象进行加密 普通加密:
import hashlib md5 = hashlib.md5() # 初始化使用md5加密方式的对象
md5.update("zxd666".encode("utf-8")) # 向对象添加要加密的内容,内容必须为字节码
print(md5.hexdigest()) # 进行加密 运行结果:
fe02a10cda698ceb5a03022189199c49 # 相同明文,密文一定相同加盐加密:
- 固定加盐:
 
import hashlib md5 = hashlib.md5("盐".encode("utf-8")) # 在初始化时可以对要加密的明文进行固定加盐,盐也需要转换为字节码
md5.update("zxd666".encode("utf-8"))
print(md5.hexdigest()) 运行结果:
2bc9ae4e838be80068a6e4963626b92c # 相同明文,密文一定相同- 动态加盐:
 
import hashlib user = input("账号:")
pwd = input("密码:")
md5 = hashlib.md5(user.encode("utf-8")) # 利用账号来给密码加盐,每个人的账号都不同,起到了动态加盐的效果
md5.update(pwd.encode("utf-8"))
print(md5.hexdigest()) 运行结果:
账号:zxd
密码:zxd123
ddca7a4709d99ac8d1b3012b2e6a364aobj.update()方法可以多次添加需要加密的内容import hashlib md5 = hashlib.md5()
md5.update("zxd".encode("utf-8"))
md5.update("666".encode("utf-8")) # 可以分开多次添加
print(md5.hexdigest()) 运行结果:
fe02a10cda698ceb5a03022189199c49 # 与上面例子中普通加密的密文相同
模块应用二:用于文件一致性校验
- linux讲究:一切皆文件,我们普通的文件,视频,音频,图片,以及应用程序等都是文件。我们都从网上下载过资源,比如我们下载的Python解释器,当时你可能没有注意过,其实你下载的时候都是带一个MD5或者shax值的,为什么? 我们的网络世界是很不安全的,经常会遇到病毒,木马等,有些你是看不到的可能就植入了你的电脑中,那么他们是怎么来的? 都是通过网络传入来的,就是你在网上下载一些资源的时候,趁虚而入,当然大部分被我们的浏览器或者杀毒软件拦截了,但是还有一部分偷偷的进入你的磁盘中了。那么我们自己如何验证我们下载的资源是否有病毒呢?这就需要文件的一致性校验了。在我们下载一个软件时,往往都带有一个MD5或者shax值,当我们下载完成这个应用程序时你要是对比大小根本看不出什么问题,你应该对比他们的md5值,如果两个md5值相同,就证明这个应用程序是安全的,如果你下载的这个文件的MD5值与服务端给你提供的不同,那么就证明你这个应用程序肯定是植入病毒了(文件损坏的几率很低),那么你就应该赶紧删除,不应该安装此应用程序。
 - 我们之前说过,md5计算的就是bytes类型的数据的转换值,同一个bytes数据用同样的加密方式转化成的结果一定相同,如果不同的bytes数据(即使一个数据只是删除了一个空格)那么用同样的加密方式转化成的结果一定是不同的。所以,hashlib也是验证文件一致性的重要工具。
 

文件校验实例:
import hashlib def file_check(file_path):
with open(file_path,mode='rb') as f1:
sha256 = hashlib.md5()
while 1:
content = f1.read(1024)
if content:
sha256.update(content)
else:
return sha256.hexdigest()
print(file_check('python-3.6.8-amd64.exe'))
(三)collections模块
- collections模块提供了一些额外的数据类型和一些集合类的操作
 
之前提到过的官方判断可迭代对象和迭代器的方法:Iterable、Iterator
from collections import Iterable, Iterator lst = [1,2,3,4,5]
l_iter = iter(lst)
print(isinstance(lst, Iterable))
print(isinstance(l_iter, Iterator)) 运行结果:
True
TrueCounter类(统计)
- Counter类是一个计数器,可以用来统计每个元素出现的次数,返回的是一个Counter对象
 
from collections import Counter lst = [1, 2, 6, 2, 4, 4, 6, 2, 4, 5, 4, 4, 2, 3, 2, 1]
print(dict(Counter(lst))) 运行结果:
{1: 2, 2: 5, 6: 2, 4: 5, 5: 1, 3: 1}- Counter还可以用来去重
 
from collections import Counter lst = [1, 2, 6, 2, 4, 4, 6, 2, 4, 5, 4, 4, 2, 3, 2, 1]
print(list(Counter(lst))) 运行结果:
[1, 2, 6, 4, 5, 3]deque类(双向队列)
- deque类是一个双向队列,在双向队列之前先了解一下 栈 和 队列 的定义
- 栈:FILO 先进后出(比如上下电梯轿厢)
 - 队列:FIFO 先进先出(所有的排队)
 
 - 利用deque类来建立双向队列,以及操作双向队列
 
from collections import deque q = deque()
q.append(3)
q.append(4)
q.appendleft(2)
q.appendleft(1)
print(list(q))
print(q.pop())
print(q.popleft())
print(list(q)) 运行结果:
[1, 2, 3, 4]
4
1
[2, 3]- deque类是一个双向队列,在双向队列之前先了解一下 栈 和 队列 的定义
 OrderedDict类(有序字典)
- 顾名思义,通过OrderedDict类创建的字典是有序的
 
from collections import OrderedDict dic = {"k1": 1, "k2": 2, "k3": 3}
print(dic)
od = OrderedDict({"k1": 1, "k2": 2, "k3": 3})
print(od)
print(od["k1"]) 运行结果:
{'k1': 1, 'k2': 2, 'k3': 3}
OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)]) # 位置固定
1 # 可以像正常字典取值defaultdict类(默认字典)
- 通过defaultdict类创建的字典可以给字典设置默认值,当key不存在时,直接获取默认值
 
from collections import defaultdict df = defaultdicr(list)
print(df["k1"]) 运行结果:
[]namedtuple类(命名元组)
- 通过namedtuple类创建元组可以给元组内的元素命名
 
from collections import namedtuple nt = namedtuple("num", ["x", "y"]) # 定义元组名、元素名(其实这里是创建了一个类)
p = nt(1, 2)
print(p)
print(p.x)
print(p.y) 运行结果:
num(x=1, y=2)
1
2
二、软件开发规范
软件开发规范:分文件管理,增强耦合性
bin 启动文件目录 lib 公共组件目录 core 主逻辑目录 db 相关数据目录 log 日志 conf 配置文件目录 
Python基础(十六)的更多相关文章
- Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery
		
PyQuery:一个类似jquery的python库 学习一时爽,一直学习一直爽 Hello,大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了 BeautifulSoup 美味 ...
 - Python 爬虫十六式 - 第七式:正则的艺术
		
RE:用匹配来演绎编程的艺术 学习一时爽,一直学习一直爽 Hello,大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了 pyquery 今天我们将迎来我们数据匹配部分的最后一位 ...
 - Python 爬虫十六式 - 第五式:BeautifulSoup-美味的汤
		
BeautifulSoup 美味的汤 学习一时爽,一直学习一直爽! Hello,大家好,我是Connor,一个从无到有的技术小白.上一次我们说到了 Xpath 的使用方法.Xpath 我觉得还是 ...
 - Python 爬虫十六式 - 第一式:HTTP协议
		
HTTP:伟大而又无闻的协议 学习一时爽,一直学习一直爽! Hello,大家好啊,我是Connor,一个从无到有的技术小白.有的人一说什么是HTTP协议就犯愁,写东西的时候也没想过什么是HTTP协 ...
 - Bootstrap<基础十六> 导航元素
		
Bootstrap 提供的用于定义导航元素的一些选项.它们使用相同的标记和基类 .nav.Bootstrap 也提供了一个用于共享标记和状态的帮助器类.改变修饰的 class,可以在不同的样式间进行切 ...
 - Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)
		
Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: 将一些东西封装到一个地方,你还可以取出来( ...
 - Python基础知识(六)------小数据池,集合,深浅拷贝
		
Python基础知识(六)------小数据池,集合,深浅拷贝 一丶小数据池 什么是小数据池:  小数据池就是python中一种提高效率的方式,固定数据类型使用同一个内存地址 代码块 :  一个文 ...
 - Python爬虫十六式 - 第四式: 使用Xpath提取网页内容
		
Xpath:简单易用的网页内容提取工具 学习一时爽,一直学习一直爽 ! Hello,大家好,我是Connor,一个从无到有的技术小白.上一次我们说到了 requests 的使用方法.到上节课为止, ...
 - Python爬虫十六式 - 第三式:Requests的用法
		
Requests: 让 HTTP 服务人类 学习一时爽,一直学习一直爽 Hello,大家好,我是Connor,一个从无到有的技术小白.今天我们继续来说我们的 Python 爬虫,上一次我们说到了 ...
 - Python 爬虫十六式 - 第二式:urllib 与 urllib3
		
Python请求标准库 urllib 与 urllib3 学习一时爽,一直学习一直爽! 大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了什么是HTTP协议,那么这一次我们就要动 ...
 
随机推荐
- Java版SockeDemo案例,有很详细的注释
			
一般是用一个线程池来处理接受到的请求 直接上代码(一) ServerThread层 import java.io.BufferedReader; import java.io.InputStreamR ...
 - Servlet,过滤器和监听器的配置和使用
			
一.什么是Servlet Servlet使用Java语言实现的程序,运行于支持Java语言的Web服务器或者应用服务器中.Servlet先于JSP出现,提供和客户端动态交互的功能.Servlet可以处 ...
 - java设计模式9.备忘录模式、访问者模式、调停者模式
			
备忘录模式 备忘录模式又叫快照模式,备忘录对象是一个用来存储另外一个对象内部状态快照的对象.备忘录的用意是在不破坏封装的条件下,将一个对象的状态捕捉,并外部化存储起来,从而可以在将来合适的时候把这个对 ...
 - Badboy - 导出脚本,用于JMeter并发测试
			
参考: http://leafwf.blog.51cto.com/872759/1141011 http://www.51testing.com/html/00/130600-1367743.html ...
 - 牛客小白月赛6 I 公交线路 最短路 模板题
			
链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...
 - 用webpack构建一个常规项目,好处和坏处分析
			
最近项目改版,用webpack重新架构. 些许心得我会写几篇记录一下. 好处如下: 1.ES6语法用起来,babel-loader转义,各种新语法用起来. 2.import 语法写起来,webpack ...
 - 逆向破解之160个CrackMe —— 030
			
CrackMe —— 030 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
 - .NET框架之“小马过河”
			
.NET框架之"小马过河" 有许多流行的.NET框架,大家都觉得挺"重",认为很麻烦,重量级,不如其它"轻量级"框架,从而不愿意使用.面对形 ...
 - Elasticsearch(7) --- 复合查询
			
Elasticsearch(7) ---复合查询 复合查询有:bool query(布尔查询).boosting query(提高查询).constant_score(固定分数查询).dis_max( ...
 - win7右下角声音图标不见了
			
场景:开机后发生右下角的声音图标不见了,马上google,可能性有两种图标隐藏或者系统错误 隐藏处理方式:右下角下打开自定义--> 将它调为显示和通知(发生不好使,估计是系统错误) 系统错误处理 ...