今日学习目标:
- 学习运用hashlib加密模块、logging日志模块、第三方模块。
学习内容:
- hashlib加密模块
- logging日志模块
- 第三方模块的下载与使用
内容详情
- hashlib加密模块
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。什么是摘要算法呢?摘要算法又称哈希算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串。
加密的模块用法举例
import hashlib
md = hashlib.md5() # 生成一个具有加密功能的对象
md.update('hello'.encode('utf-8')) # 往对象里传明文数据 update只能接受bytes类型的数据
md.update(b'hi') # 往对象里传明文数据 update只能接受bytes类型的数据
print(md.hexdigest()) # 获取明文数据对应的密文
分多次传入内容,但是生成的密文还是一样的
md = hashlib.md5()
md.update(b'hello')
md.update(b'he')
md.update(b'llo')
print(md.hexdigest()) # 23b431acfeb41e15d466d75de822307c
23b431acfeb41e15d466d75de822307c
注意
- 不同的算法 使用方法是相同的
密文的长度越长 内部对应的算法越复杂
但是- 时间消耗越长
- 占用空间更大
- 通常情况下使用md5算法 就可以足够了
使用场景
1. 密码的密文存储
2. 校验文件内容是否一致
思考
该类方法虽然与编码与解码相类似,但当明文被加密后是不能被解密的,并且加密的密文也是固定的。所以对于一些简单的明文加密后确实可以进行破解,但是破解方法也是比较暴力的穷举法,一个答案一个答案去验证。
对于上述情况外面的公司为了防止自己的数据被解密,就对自己的密文进行了复杂处理,方法也有了两种:
-
加盐处理
import hashlib md = hashlib.md5() # 公司自己在每一个需要加密的数据之前 先手动添加一些内容 md.update(b'oldboy.com') # 加盐处理 md.update(b'hello') # 真正的内容 print(md.hexdigest())
-
动态加盐
import hashlib def get_md5(data): md = hashlib.md5() md.update('加盐'.encode('utf-8')) md.update(data.encode('utf-8')) return md.hexdigest() password = input('password>>>:') res = get_md5(password) print(res)
- logging日志模块
日志模块记录程序运行过程中的各种状态。- 日志有五个等级
-
CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
-
ERROR:发生错误时,如IO操作失败或者连接问题
-
WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误
-
INFO:处理请求或者状态变化等日常事务
-
DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态
如何去使用呢,有大致的模板,copy过来即可
import logging
logging.basicConfig(filename='access.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',#p是上下午
level=30,#级别,比30大的都会记录
)#这么多参数瞄一眼,不需要记住
logging.debug('debug日志') # 10
logging.info('info日志') # 20
logging.warning('warning日志') # 30
logging.error('error日志') # 40
logging.critical('critical日志') # 50
(简单的日志)使用流程:8步
- logger对象:负责产生日志。logger.getLogger()方法填写日志的名字
- filter对象:过滤日志(了解)
- handler对象:控制日志输出的位置(存放到文件/终端)可以有多个
- formmater对象:规定日志内容的格式。
- 给logger对象绑定handler对象:addHandler()
- 给handler绑定输出格式(formmate).setFmatter()方式
- 设置日志等级.setLevel()
- 写日志.debug()
运用举例
import logging
# 1.logger对象:负责产生日志
logger = logging.getLogger('程序功能说明')
# 2.filter对象:过滤日志(了解)
# 3.handler对象:控制日志输出的位置(文件/终端)
hd1 = logging.FileHandler('a.log',encoding='utf-8') # 输出到文件中
hd2 = logging.StreamHandler() # 输出到终端
# 4.formmater对象:规定日志内容的格式
fm1 = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
)
fm2 = logging.Formatter(
fmt='%(asctime)s - %(name)s: %(message)s',
datefmt='%Y-%m-%d',
)
# 5.给logger对象绑定handler对象。即给logger对象指定输出位置
logger.addHandler(hd1)
logger.addHandler(hd2)
# 6.给handler绑定formmate对象。即给输出位置绑定输出内容的格式
hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
# 7.设置日志等级
logger.setLevel(10)
# 8.记录日志
logger.debug('运行开始')
为了简化代码编写篇幅(其实是为了”偷懒“),就依据上述代码,编写了一个模板:logging配置字典
import os
import logging.config
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
# 定义日志输出格式 结束
"""
只有下面的两个变量对应的值 需要你手动修改
"""
logfile_dir = os.path.dirname(__file__) # log文件的目录。往上一级
logfile_name = 'a3.log' # log文件名
# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
#用os模块创建一个出来
# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)
# log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},#标准格式
'simple': {
'format': simple_format
},#简单格式
},
'filters': {}, # 过滤日志(用不到,直接忽略)
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小上限 5M
'backupCount': 5,#如果上面文件满了就直接新建一个5M的文件,最多存5个。若又满了,就把开头的文件挨个删除,就好比摄像头记录信息。
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#产生名字
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
}, # 当键不存在的情况下 默认都会使用该k:v配置
},
}
# 使用日志字典配置
logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置
#接下来生成一个对象
logger1 = logging.getLogger('asajdjdskaj')#必须注意该名字必须在上面的logger中定义,否则无内容记录。因此直接将上面的logger内不要定义名字,直接写空即可,程序会自动添加名字
logger1.debug('加油')
这个就是模板,以后要去编写简单日志功能就可以去复制上述代码,封装成模块去调用就可以了
logging.config.dictConfig(LOGGING_DIC) # (字典名)自动加载字典中的配置
#接下来生成一个对象
logger1 = logging.getLogger('fdsafsadfsa')#直接将上面的logger内不要定义名字,直接写空即可,程序会自动添加名字
logger1.debug('加油')
-
第三方模块的下载与使用
对于python来说,它的真正强大的地方就在于它拥有着庞大的第三方模块库。这些第三方模块的功能覆盖类绝大多数行业,所以对于程序员来说就非常有利于他们的项目编写。- 如何去使用第三方模块呢
需要使用python解释器提供的pip工具去下载模块 - 下载方式
- 方式1:直接使用命令行(cmd终端直接敲)
- pip3 install 模块名 ‘’‘该方式默认下载的是最新版本’’’
- pip3 install 模块名==版本号 ‘’‘自定义下载版本号’’’
ps:pip工具默认是从国外的仓库下载模块 速度会比较慢 可以修改pip3 install 模块名 -i 仓库地址 # 命令行临时修改地址
- 仓库地址
(1)阿里云http://mirrors.aliyun.com/pypi/simple/
(2)豆瓣http://pypi.douban.com/simple/
(3)清华大学https://pypi.tuna.tsinghua.edu.cn/simple/
(4)中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
(5)华中科技大学http://pypi.hustunique.com/
- 方式1:直接使用命令行(cmd终端直接敲)
- 方式2:利用编程软件提供的快捷方法
有些编程软件内会带有模块管理器,可以去到网上去找相应的软件下载方式。
- 如何去使用第三方模块呢
-
第三方模块举例:openpyxl:excel表格模块
2003版本之前 excel的文件后缀是xls
2003版本之后 excel的文件后缀是xlsx、csv
模块方法
-
写模块:Workbook()
from openpyxl import Workbook wb = Workbook() #先生成一个工作簿 wb.save('test.xlsx')# 保存新建的excel文件
-
创建新的表单页.create_sheet()
wb1 = wb.create_sheet('index',0) #后面的索引控制表单创建的位置。默认是从1往后
-
修改表单页名称:.title
wb1.title = 'login'
-
为表单赋值
在新创建(wb1=wb.create_sheet(‘名称’,索引))的表单页上填写数据wb1['A3'] = 123 wb1['A4'] = 456
指定具体某行某列的数据
wb1.cell(row=6,column=3,value=88888888)
加入函数功能
wb1['A5'] = '=sum(A3:A4)'
按照一行一行的顺序传值
wb1.append(['username','age','hobby']) wb1.append(['张三',20,'学习']) wb1.append(['李四',18,'吃饭']) wb1.append(['王二',23,'睡觉']) wb1.append(['麻子',25,'跑步']) # 保存新建的excel文件 # wb.save('test.xlsx')
-
openpyxl读文件load_workbook
from openpyxl import load_workbook#读文件 wb = load_workbook('test.xlsx',read_only=True,data_only=True) print(wb['login']['A3'].value) print(wb['login']['A4'].value) print(wb['login']['A5'].value) # 通过代码产生的excel表格必须经过人为操作之后才 能读取出函数计算出来的结果值 res = wb['login'] # print(res) ge1 = res.rows for i in ge1: for j in i: print(j.value)
学习时间:
- 周一至周五晚上 7 点—晚上9点
- 周六上午 9 点-上午 11 点
- 周日下午 3 点-下午 6 点
学习产出:
- CSDN 技术博客 1 篇
- 今日学习内容回顾语音 1个