day23_常用模块2

目录


1.什么是序列化

序列化指的是把内存的数据类型转换成一个特定的格式的内容
该格式的内容可用于存储或者传输给其他平台使用

内存中的数据类型--->序列号---->特定的格式(json格式或者pickle格式)
内存中的数据类型<---反序列号<----特定的格式(json格式或者pickle格式)

为何要序列号
序列化得到特定格式的结果有两种用途
1.可用于存储 => 用于存档
2.传输给其他平台使用 => 跨平台数据交互

强调
针对用途一的特定格式:可以是一种专用的格式=>pickle只有python可以识别
针对用途二的特定格式:应该是一种通用,能够被各种语言识别的格式=>

如何序列化和反序列化

json模块

import json
json_res=json.dumps(['aaa',True,False])
print(json_res)
with open('a.txt','w',encoding='utf-8') as f:
    f.write(json_res)
    # json.dump(['aaa',True,False],f)

l=json.loads(json_res)
print(l,type(l))
with open('a.txt','r',encoding='utf-8') as f:
    res=f.read()
    l=json.loads(res)
    # l=json.load(f)
    print(l)

json验证:json格式兼容的是所有语言通用的数据类型,不能识别某已语言所独有类型
json.loads({1,2,3,4,5})

强调
json字符串格式用" " 双引号
json反序列化必须用json格式,也可以在之前+b
l=json.loads(b'["aaa",True,False]')

pickle模块

import pickle
res=pickle.dumps({1,2,3,4,5})
print(res,type(res))

s=pickle.loads(res)
print(s,type(s))

= = = = = = = =了解= = = = = = = = =

coding:utf-8
import pickle

with open('a.pkl',mode='wb') as f:
    # 一:在python3中执行的序列化操作如何兼容python2
    # python2不支持protocol>2,默认python3中protocol=4
    # 所以在python3中dump操作应该指定protocol=2
    pickle.dump('你好啊',f,protocol=2)

with open('a.pkl', mode='rb') as f:
    # 二:python2中反序列化才能正常使用
    res=pickle.load(f)
    print(res)

2.猴子补丁

一.什么是猴子补丁?
猴子补丁的核心就是用自己的代码替换所用模块的源代码,详细地如下
1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。

二. 猴子补丁的功能(一切皆对象)
1.拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)

class Monkey:
    def hello(self):
        print('hello')

    def world(self):
        print('world')


def other_func():
    print("from other_func")


monkey = Monkey()
monkey.hello = monkey.world
monkey.hello()
monkey.world = other_func
monkey.world()

三.monkey patch的应用场景
如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高,
但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能会想到这么做
import ujson as json
但是这么做的需要每个文件都重新导入一下,维护成本依然很高,此时我们就可以用到猴子补丁了, 只需要在入口加上:

import json
import ujson

def monkey_patch_json():
    json.__name__ = 'ujson'
    json.dumps = ujson.dumps
    json.loads = ujson.loads

monkey_patch_json() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果

其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey
Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey
Patch带了便利的同时也有搞乱源代码的风险


3.configparser模块

配置文件格式

import configparser
config=configparser.ConfigParser()
config.read('test.ini')

获取section
print(config.sections())

获取section下的options
print(config.options('section1'))

获取items
print(config.items('section1'))

获取值
print(config.get('section1','user'))
print(config.getint('section1','age'))

4.hashlib模块

1.什么是hash:
hash一类算法,该算法接受传入的内容,经过运算得到一串hash值

hash值的特点:
I 只要传入的内容一样,得到的hash值必然一样
II 不能由hash值返解成内容
III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定

2、hash的用途
用途1:特点II用于密码密文传输与验证
用途2:特点I、III用于文件完整性校验

3.如何用hash

import hashlib
m=hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
res=m.hexdigest()

f=open('a.txt','rb')
f.seek()
f.read(2000)
m.update()
m.hexdigest()

模拟撞库

import hashlib
cryptograph = 'aee949757a2e698417463d47acac93df'

passwds = [
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
]

dic = {}
for i in passwds:
    res = hashlib.md5(i.encode('utf-8'))
    dic[i] = res.hexdigest()

for k, v in dic.items():
    if v == cryptograph:
        print(f'撞库成功,明文密码是{k}')
        break

提升撞库的成本=>密码加盐

import hashlib

m=hashlib.md5()

m.update('天王'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('盖地虎'.encode('utf-8'))
print(m.hexdigest())


import subprocess

obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj)
res=obj.stdout.read()
print(res.decode('utf-8'))

err_res=obj.stderr.read()
print(err_res.decode('utf-8'))
homework
# 1、把登录与注册的密码都换成密文形式
import hashlib
def register():
    inp_usernmae=input('请输入用户名:')
    inp_password=input('请输入密码:')
    re_password=input('请再次输入密码:')
    if inp_password==re_password:
        m=hashlib.md5()
        m.update(inp_password.encode('utf-8'))
        password=m.hexdigest()
        print('注册成功')
        with open('db.txt','w',encoding='utf-8') as w:
            w.write(f'{inp_usernmae}:{password}\n')
    else:
        print('两次密码不一致')

def login():
    while True:
        inp_username=input('请输入账号:')
        inp_password=input('请输入密码:')
        with open('db.txt','r',encoding='utf-8') as f:
            for line in f:
                user,pwd=line.strip().split(':')
                if inp_username==user:
                    m=hashlib.md5()
                    m.update(inp_password.encode('utf-8'))
                    inp_password=m.hexdigest()
                    if inp_password==pwd:
                        print('登录成功')
                        return
                    else:
                        print('密码错误')


# 2、文件完整性校验(考虑大文件)
m=hashlib.md5()
f=open('a.txt','rb')
f.seek()
f.read(2000)
m.update()
m.hexdigest()

# 3、注册功能改用json实现
import hashlib
import json
def register():
    inp_username=input('请输入用户名:')
    inp_password=input('请输入密码:')
    re_password=input('请再次输入密码:')
    if inp_password==re_password:
        m=hashlib.md5()
        m.update(inp_password.encode('utf-8'))
        password=m.hexdigest()
        print('注册成功')
        with open('db.txt','w',encoding='utf-8') as w:
            user=json.dumps([inp_username])
            pwd=json.dumps([password])
            w.write(f'{user}:{pwd}')
    else:
        print('两次密码不一致')

# 4、项目的配置文件采用configparser进行解析
import configparser
config=configparser.ConfigParser()
config.read('test.ini')

# 获取section
print(config.sections())

# 获取section下的options
print(config.options('section1'))

# 获取items
print(config.items('section1'))

返回

猜你喜欢

转载自www.cnblogs.com/wjxyzs/p/12910850.html
今日推荐