python常用模块详解2

序列化模块补充:

1.json格式的限制,json格式的key必须是字符串数据类型
2.json格式的字符串必须是""
如果数字是key,那么dump之后会强转成字符串数据类型
import json
dic = {1:2,3:4}
str_dic = json.dumps(dic)
print(str_dic)#{"1": 2, "3": 4}
new_dic = json.loads(str_dic)
print(new_dic)#{'1': 2, '3': 4}
json是否支持元组,对元组做value的字典会把元组强制转换为列表.
import json
dic = {"abc":(1,2,3)}
str_dic = json.dumps(dic)
print(str_dic)#{"abc": [1, 2, 3]}
new_dic = json.loads(str_dic)
print(new_dic)#{'abc': [1, 2, 3]}
json是否支持元组做key?不可以.
import json
dic = {(1,2,3):"abc"}
str_dic = json.dumps(dic)
print(str_dic)#TypeError: keys must be a string
new_dic = json.loads(str_dic)
print(new_dic)
对列表的dump.
import json
lst = [1,2,"abc",12.3]
with open("json_demo",'w')as f:
    json.dump(lst,f)
with open('json_demo')as f:
    ret = json.load(f)
    print(ret)#[1, 2, 'abc', 12.3]
能不能多次dump数据到文件里,可以多次dump但不能load出来.
import json
dic = {'abc':(1,2,3)}
lst = [1,2,3,"abc",12.3]
with open('json_demo','w')as f:
    json.dump(dic,f)
    json.dump(lst,f)    #{"abc": [1, 2, 3]}[1, 2, 3, "abc", 12.3]
with open("json_demo")as f:
    ret = json.load(f)
    print(ret)
想dump多个数据到文件里用dumps
import json
dic = {'abc':(1,2,3)}
lst = [1,2,3,"abc",12.3]
with open("json_demo",'w')as f:
    str_dic = json.dumps(dic)
    str_lst = json.dumps(lst)
    f.write(str_dic+"\n")
    f.write(str_lst+'\n')
with open('json_demo')as f:
    for line in f:
        ret = json.loads(line)
        print(ret)
#{'abc': [1, 2, 3]}
#[1, 2, 3, 'abc', 12.3]
中文格式 (ensure_ascii = False)
import json
dic = {"abc":(1,2,3,),"country":"中国"}
ret = json.dumps(dic,ensure_ascii=False)
print(ret)#{"abc": [1, 2, 3], "country": "中国"}
dic_new = json.loads(ret)
print(dic_new)#{'abc': [1, 2, 3], 'country': '中国'}

with open("json_demo","w")as f:
    json.dump(dic,f)
with open("json_demo")as f:
    ret = json.load(f)
    print(ret)#{'abc': [1, 2, 3], 'country': '中国'}
json的其他参数,是为了用户看的更方便,但是会相对浪费空间.
import json
data = {"username":["李华","李二楞"],"sex":"male",'age':21}
json_dic = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)
print(json_dic)
# {
#     "age":21,
#     "sex":"male",
#     "username":[
#         "李华",
#         "李二楞"
#     ]
# }
注:set不能被dump/dumps
序列化模块之pickle

dump的结果是bytes,dump用的f文件句柄需要以wb的形式打开,load所用的模式是rb模式
支持几乎所有对象的序列化
对于对对象的序列化需要这个对象的类在内存中
对于多次的dump和load的操作做了良好的处理
import pickle
dic = {1:(1,2,3),("abc","def"):1.23}
pic_dic = pickle.dumps(dic)
print(pic_dic)#bytes类型
new_dic = pickle.loads(pic_dic)
print(new_dic)#{1: (1, 2, 3), ('abc', 'def'): 1.23}
pickle几乎支持所有对象的序列化.
import pickle
class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age

alex = Student("alex",83)
ret = pickle.dumps(alex)
print(ret)#bytes类型
new_ret = pickle.loads(ret)
print(new_ret.name)#alex
print(new_ret.age)#83

with open("pickle_demo",'wb')as f:
    pickle.dump(alex,f)
with open("pickle_demo",'rb')as f:
    a = pickle._load(f)
    print(a.name)#alex
    print(a.age)#83
序列化模块之shelve:
import shelve
f = shelve.open("shelve_demo")
f['key'] = {'k1':123,'k2':'k3'}
f.close()
f = shelve.open("shelve_demo")
ret = f['key']
f.close()
print(ret)#{'k1': 123, 'k2': 'k3'}
shelve如果你写定了一个文件,改动的比较少,读文件的操作比较多,且你大部分的读取都需要基于某个key获得某个value

hashilib模块(摘要算法的模块):

能够把一个字符串的数据类型的变量转换成一个定长的,密文的字符串,字符串里的每一个字符都是一个十二禁止的数字

对于同一个字符串,不管这个字符串有多长,只要是相同的,无论在任何环境下,多少次执行,在任何语言中,
使用相同的算法/相同的手段得到的结果都是相同的.如果不是相同的字符串,得到的结果一定不同
算法:对于相同的字符串,用相同的算法,相同的手段,得到的值一定是相同的
md5是一个算法,32位的字符串,每个字符都是一个十六进制
md5算法:效率快,算法相对简单

import hashlib
s1 = 'alex3714'
s2 = 'alex21348174612571'
md5_obj = hashlib.md5()
md5_obj.update(s1.encode("utf-8"))
res = md5_obj.hexdigest()
print(res,len(res),type(res))
#aee949757a2e698417463d47acac93df 32 <class 'str'>
数据库->撞库
import hashlib
s1 = '1232312'
md5_oobj = hashlib.md5()
md5_oobj.update(s1.encode('utf-8'))
res = md5_oobj.hexdigest()
print(res,len(res),type(res))
# f7fc239ea412bcec46a2c6ca3a58c517 32 <class 'str'>
加盐
import hashlib
s1 = 'corn123'#1c22330a641d90698dbdf1ae3a10a6a6 32 <class 'str'>
md5_obj = hashlib.md5('任意的字符串作为盐'.encode('utf-8'))
md5_obj.update(s1.encode('utf-8'))
res = md5_obj.hexdigest()
print(res,len(res),type(res))
#00ed5d09379b4287cc1654705aeb6cd8 32 <class 'str'>
动态加盐:
用用户名作为加盐,因为用户名不能相同,这样比较安全.
import hashlib
username = input('username>>>')
password = input("password>>>")
md5_obj = hashlib.md5(username.encode("utf-8"))
md5_obj.update(password.encode('utf-8'))
res = md5_obj.hexdigest()
print(res,len(res),type(res))
sha1也是一种算法,40位的字符串,每个字符都是一个十六进制.
算法相对复杂,计算也慢.
import hashlib
s1 = 'corn'
sha1_obj = hashlib.sha1()
sha1_obj.update(s1.encode('utf-8'))
res = sha1_obj.hexdigest()
print(res,len(res),type(res))
#7cacb75c4cc31d62a6c2a0774cf3c41a70f01bc0 40 <class 'str'>
sha1算法加盐.
import hashlib
s1 = 'corn'
sha1_obj = hashlib.sha1('123'.encode('utf-8'))
sha1_obj.update(s1.encode('utf-8'))
res = sha1_obj.hexdigest()
print(res,len(res),type(res))
#dbd08e07817591b800c61a43ab5664bbf65a4b69 40 <class 'str'>
sha1算法动态加盐.
import hashlib
username = input("username>>>")
password = input("password>>>")
sha1_obj = hashlib.sha1(username.encode('utf-8'))
sha1_obj.update(password.encode('utf-8'))
res = sha1_obj.hexdigest()
print(res,len(res),type(res))
md5和sha1的区别:
md5:32位字符串,目前 MD5 是一种不可逆算法。具有很高的安全性。它对应任何字符串都可以加密成一段唯一的固定长度的代码。
sha1:40位字符串,sha1基于md5,加密后的数据长度更长,它对长度小于 24的输入,产生长度为160bit的散列值.比md5多32位.因此,比md5更加安全,但sha1的运算速度就比md5要慢了。

文件的一致性校验.
import hashlib
md5_obj = hashlib.md5()
with open('shelve_demo.dir','rb')as f:
    md5_obj.update(f.read())
    ret = md5_obj.hexdigest()
md5_obj = hashlib.md5()#需要实例化两次
with open("shelve_demo.bak",'rb')as f:
    md5_obj.update(f.read())
    ret1 = md5_obj.hexdigest()
    print(ret,ret1)
#d4d69a04f38df23025caf0ed85f9961c d4d69a04f38df23025caf0ed85f9961c
configparser模块:
有一种固定格式的配置文件,有一个对应的模块去帮你做这个文件的字符串处理

setting.py 配置
import configparser

corn = configparser.ConfigParser()
corn['DEFAULT'] = {'ServerAliveInterval':'45',
                   'Compression':'yes',
                   'CompressionLevel':'9',
                   'ForwardX11':'yes'
                   }

corn['bitbucket.org'] = {'User':'hg'}
corn['topsecret.serve.com'] = {'Host port':'50022','ForwardX11':'no'}

with open('example.ini','w')as f:
    corn.write(f)
logging模块:

1.日志格式的规范
2.操作的简化
3.日志的分级管理

logging 不能帮你做的事情.
1.自动帮你打印你要打印的内容
2.需要程序员自己在开发过程中定义好
3.在哪些地方需要打印,要打印的内容是什么,内容级别

logging模块的使用:
1.普通配置型 简单的,可定制化差
2.对象配置型 复杂的,可定制化强

认识日志分级
import logging

logging.debug("debug message")  #调试模式
logging.info("info message")    #基础信息
logging.warning("warning message")#警告
logging.error("error message")  #错误
logging.critical("critical message")#严重错误

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                    filename='test.log')
logging.debug('debug message')      # 调试模式
logging.info('info message')        # 基础信息
logging.warning('warning message')  # 警告
logging.error('error message')      # 错误
logging.critical('critical message')# 严重错误

basicConfig
# 不能将一个log信息既输出到屏幕 又输出到文件
logger对象的形式来操作日志文件

创建一个logger对象
创建一个文件管理操作符
创建一个屏幕管理操作符
创建一个日志输出的格式

文件管理操作符 绑定一个 格式
屏幕管理操作符 绑定一个 格式

logger对象 绑定 文件管理操作符
logger对象 绑定 屏幕管理操作符

import logging
# 创建一个logger对象
logger = logging.getLogger()
# 创建一个文件管理操作符
fh = logging.FileHandler('logger.log',encoding='utf-8')
# 创建一个屏幕管理操作符
sh = logging.StreamHandler()
# 创建一个日志输出的格式
format1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 文件管理操作符 绑定一个 格式
fh.setFormatter(format1)
# 屏幕管理操作符 绑定一个 格式
sh.setFormatter(format1)
logger.setLevel(logging.DEBUG)
# logger对象 绑定 文件管理操作符
# logger.addHandler(fh)
# logger对象 绑定 屏幕管理操作符
logger.addHandler(sh)

logger.debug('debug message')      # 调试模式
logger.info('我的信息')        # 基础信息
logger.warning('warning message')  # 警告
logger.error('error message')      # 错误
logger.critical('critical message')# 严重错误

猜你喜欢

转载自www.cnblogs.com/zycorn/p/9456383.html