python学习第二十天

一、包

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.关于包相关的导入语句也分为importfrom ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

3import导入文件时,产生名称空间中的名字来源于文件,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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值