Day16 模块与包介绍以及json/pickle/hashlib模块的常用方法

第五周:

Day 16

模块与包

1、什么是包

​ 包是作为目录存在的,包的另外一个特点就是文件中有一个__init__.py文件,如果我们忘记创建这个文件夹,就没法从这个文件夹里面导入那些模块。一句话来说包是一个含有__init__.py文件的文件夹,本质就是一个模块,是用来被导入的

2、为何要有包

​ 包的作用和模块的作用是相似的,因为很多功能没有自带,当我们需要使用这些功能的时候,可以通过下载标准库,第三方或者自定义一个拥有相同功能模块的含有__init__.py文件文件夹,通过import导入相关方法来完成自己的项目

3、包的使用

首次导入包这种模块主要做了两件事

1)创建模块的名称空间,运行包下的__init__.py文件,将运行过程中产生的名称都丢入模块的名称空间中

​ 实际上就是我们无法给包(文件夹)创建名称空间,所以用__init__来代替给包创建

2)在当前位置拿到一个名字Package,该名字指向__init__.py的名称空间,即Package名字,名字是来自于__init__.py中的文件的名称空间,即Package名称空间

当包与执行文件(run)不在同级目录下时需要额外将包的路径添加到环境变量中(sys.path)这一步是使用者来执行的,

那我们在创建了一个多级包目录的时候各级包的导入是怎么样的呢?
在这里插入图片描述

我们可以这样导入

3) run文件导包

from Package1.Package2.Package3 import Module31

Module31.m31()

4)下级文件导包逐级导入①从根目录向下导入

# ①Module 32

from Package1 import Module11

from Package1.Package2 import Module21

Module11.m11()
Module21.m21()

​ 下级文件导包②相对导入只适用于包中的模块,顶层的模块中将不起作用(不能超过根目录

from ... import Module11

from .. import Module21

Module11.m11()
Module21.m21()
#from ... import Module11
#ValueError: attempted relative import beyond top-level package
  • 如果将Run.py当作顶层执行模块

    • 2和 B将成为 **toplevel package 顶层包** 2中的模块不能用相对导入来导入B包中的模块,因为不能越过顶层包。
    • 2、B 包中的目录可以导入本包中及以下的模块

2、json\ pickle模块

1、什么是序列化与反序列化

​ 内存中某一类的数据---------------》特殊的格式
​ 内存中某一类的数据《---------------特殊的格式

2、为何要序列化

​ 1、存档:把内存中的数据持久化到硬盘
​ 2、跨平台交互数据

在python中:
    存档=》推荐用pickle格式
    跨平台交互=》推荐用json格式

3、如何序列化

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、用json来序列化

​ 优点:跨平台交互数据

​ 缺点:无法识别所有的python数据类型

​ 注意: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))

注意:

load:针对文件句柄,将json格式的字符转换为dict,从文件中读取 (将string转换为dict)

with open("a.json", mode='rt', encoding='utf-8') as f:
    dic = json.loads(f)

loads:针对内存对象,将string转换为dict (将string转换为dict)

a = json.loads('{'a':'1111','b':'2222'}')

2. dump 和 dumps(序列化)

dump:将dict类型转换为json字符串格式,写入到文件 (易存储)

with open("b.json", mode='wt', encoding='utf-8') as f:
    json.dump(t, f)

dumps:将dict转换为string (易传输)

a_dict = {'a':'1111','b':'2222'}
a_str = json.dumps(a_dict)

3.pickle

优点:可以识别所有python类型

缺点:只能用于python中,无法跨平台交互pickle序列化后的数据,可读性差,人一般无法识别

1. pickle.dump(obj, file, [,protocol])

  • 函数的功能:接受一个文件句柄和一个数据对象作为參数,把数据对象obj以特定的格式保存到给定的文件file里。

  • 参数:

    obj:想要序列化的obj对象。
    file:文件名称。
    protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。

2.pickle.load(file)

函数的功能:将file中的对象序列化读出。

  • 参数:
    file:文件名称。
import pickle

s = {1, 2, 3, 4, 5}

res = pickle.dumps(s)
# print(res,type(res))
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))

3、hashlib模块

hash是一种算法(md5\sha256\sha512等),我们为该算法传入内容,该算法会计算得到一串hash值
hash值具备以下三个特点:
1、如果传入的内容一样,并且采用hash算法也一样,那么得到个hash值一定是一样的
2、hash值的长度取决于采用的算法,与传入的文本内容的大小无关
3、hash值不可逆

MD5是最常见的摘要算法,速度很快,生成结果是固定的16字节,通常用一个32位的16进制字符串表示。SHA1算法更安全点,它的结果是20字节长度,通常用一个40位的16进制字符串表示。而比SHA1更安全的算法是SHA256和SHA512等等,不过越安全的算法越慢,并且摘要长度更长。

应用场景 :

密码加密

​ **(撞库)**很多用户喜欢用123456abcdefloveyou这些简单的口令,由于MD5、SHA1等所有摘要算法都是公开的,黑客可以事先通过这些算法计算出这些常用口令的摘要值,得到一个反推表,然后,无需暴力破解,只需要对比数据库的密码摘要,就可以获得使用常用口令的用户账号。

“加盐”

​ 额外给原始数据添加一点自定义的数据,使得生成的消息摘要不同于普通方式计算的摘要。

选取片段 做文件校验

​ 下载文件的时候选取片段做哈希加密,与源文件片段的哈希值做对比,相同就是同一个文件。

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

加盐
pwd="123"

m3=hashlib.md5()
m3.update("天王盖地虎".encode('utf-8'))
m3.update(pwd.encode('utf-8'))
m3.update("小鸡炖蘑菇".encode('utf-8'))

print(m3.hexdigest())

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页