目录
一、包
1.1、什么是包
包是一个含有__init__.py文件的文件夹,本质就是一个模块,是用来被导入的
1.2、为何要有包
随着模块数目的增多,把所有模块不加区分地放到一起也是极不合理的,于是Python为我们提供了一种把模块组织到一起的方法,即创建一个包。
aaa/ #顶级包
├── __init__.py
│ ├── m1.py
│ └── m2.py
├── bbb #子包
│ ├── __init__.py
│ ├── m3.py
│
└── 包的使用.py #子模块
强调:
#1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
#2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模
1.3、如何使用包
首次导入包这种模块,发生两件事
1、创建模块的名称空间,运行包下的__init__.py的文件,将运行过程中产生的名字都丢入模块的名称空间中
2、在当前位置拿到一个名字aaa,该名字指向__init__.py的名称空间,即aaa.名字,名字是来自于__init__.py中的
文件里的内容:
m1.py
def f1():
print('m1.f1')
m2.py
def f2():
print('m2.f2')
m3.py
def f3():
print('m3.f3')
包的使用.py
print('=====')
强调:
1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
3、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
1.4、绝对导入与相对导入
针对包内的模块之间互相导入,导入的方式有两种
1、绝对导入:以顶级包为起始
2、相对导入:.代表当前文件所在的目录,…代表当前目录的上一级目录,依此类推
import也能使用绝对导入,导入过程中同样会依次执行包下的__init__.py,只是基于import导入的结果,使用时必须加上该前缀
二、json&pickle模块
2.1、什么是序列化与反序列化
内存中某一类的数据---------------》特殊的格式
内存中某一类的数据《---------------特殊的格式
2.2、为何要序列化
1、存档:把内存中的数据持久化到硬盘
2、跨平台交互数据
在python中:
存档=》推荐用pickle格式
跨平台交互=》推荐用json格式
2.3、如何序列化
2.3.1、low的序列化与反序列化方式
1.序列化
items=["圣剑","蝴蝶","BKB"]
dic_str=str(items)
with open('db.txt',mode='wt',encoding="utf-8") as f:
f.write(dic_str)
2.反序列化
with open('db.txt',mode='rt',encoding='utf-8') as f:
data=f.read() # "['圣剑', '蝴蝶', 'BKB']"
items=eval(data)
print(items[0])
2.3.2、json方式序列化与反序列化
import json
序列化方式一:
t={"a":1,"b":2} # 字典=======》json格式的字符串:"[1,2,3]"
res=json.dumps(t)
print(res,type(res))
with open("a.json",mode='wt',encoding='utf-8') as f:
f.write(res)
json反序列化方式一:
with open("a.json",mode='rt',encoding='utf-8') as f:
data=f.read()
dic=json.loads(data)
print(dic,type(dic))
res=json.loads('{"k1":111}')
print(res['k1'])
json序列化方式二:
t={"a":1,"b":2} # 字典=======》json格式的字符串:"[1,2,3]"
with open("b.json",mode='wt',encoding='utf-8') as f:
json.dump(t,f)
json反序列化方式二:
with open("b.json",mode='rt',encoding='utf-8') as f:
dic=json.load(f)
print(dic,type(dic))
**优点:跨平台交互数据**
**缺点:无法识别所有的python数据类型**
**注意:json格式的字符串里不能包含单引号**
2.3.3、pickle方式序列化与反序列化
import pickle
s = {1,2,3,4,5}
序列化
res=pickle.dumps(s)
#print(res,type(res))#b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8f\x94(K\x01K\x02K\x03K\x04K\x05\x90.' <class 'bytes'>
with open('a.pkl',mode='wb') as f:
f.write(res)
反序列化
with open('a.pkl',mode='rb') as f:
data=f.read()
s=pickle.loads(data)
print(type(s)) # {1, 2, 3, 4, 5} <class 'set'>
**优点:可以识别所有python类型**
**缺点:只能用于python中,无法跨平台交互**
三、hashlib模块
3.1、什么是哈希
hash是一类算法,该算法接收传入的内容,经计算得到一串hash值
hash值的特点:
(1)、传入的值一样, 得到的hash结果相同=====>要用明文传输密码文件完整性校验
(2)、只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
(3)、不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码
import hashlib
m=hashlib.md5()
m.update("你好".encode('utf-8'))
m.update("egon".encode('utf-8'))
m.update("哈哈哈".encode('utf-8')) # "你好egon哈哈哈"
res=m.hexdigest()
print(res) # 824cb1b104e36de8f98ef38fbee759a5
m1=hashlib.md5("你".encode('utf-8'))
m1.update("好eg".encode('utf-8'))
m1.update("on哈哈哈".encode('utf-8')) # "你好egon哈哈哈"
res=m1.hexdigest()
print(res) # 824cb1b104e36de8f98ef38fbee759a5
m2=hashlib.md5()
with open('aaa.png',mode='rb') as f:
for line in f:
m2.update(line)
print(m2.hexdigest()) # 14c1bbbb06ba99319a42e89074346d5d
3.2、hash的用途
(1)加密明文,得到hash字符串,
123456abc=======md5=======》hash字符串
客户端==========hash字符串=========》服务端
hash字符串校对
(2)破解密码
截获hash值即密文密码
["alex 123","alex @123","alex 1234","al 123ex"]
用md5或其他方法解析明文密码,和hash值对比
(3)文件完整性校验:特点(1)(2)
f=open("b.txt",mode="rb")
f.seek()
3.3、如何用hash
import hashlib
m=hashlib.md5()
m.update("hello".encode("utf-8"))#传入的内容必须是bytes类型
m.update("world".encode("utf-8"))
res=m.hexdigest()#hello world
print(res)
import hashlib
m=hashlib.md5("he".encode("utf-8"))
m.update("llo".encode("utf-8"))
m.update("world".encode("utf-8"))
res=m.hexdigest()#hello world
print(res)
模拟撞库
import hashlib
passwds=[
'alex3714',
'alex1313',
'alex94139413',
'alex123456',
'123456alex',
'a123lex',
]
def make_passwd_dic(passwds):
dic={}
for passwd in passwds:
m=hashlib.md5()
m.update(passwd.encode('utf-8'))
dic[passwd]=m.hexdigest()
return dic
#模拟撞库得到密码
def break_code(cryptograph,passwd_dic):
for k,v in passwd_dic.items():
if v == cryptograph:
print('密码是===>\033[46m%s\033[0m' %k)
cryptograph='aee949757a2e698417463d47acac93df'
break_code(cryptograph,make_passwd_dic(passwds))
密码加盐:提升撞库成本
import hashlib
m=hashlib.md5()
m.update("天王".encode("utf-8"))
m.update("lili123".encode("utf-8"))
m.update("盖地虎".encode("utf-8"))
res=m.hexdigest()
print(res)