第三方模块补充
今日内容
- openpyxl模块的读取数据
- random模块
- hashib模块
- subprocess模块
- 日子模块
openpyxl模块的读取
opnepyxl模块时针对excel表格进行操作的模块
既然有存入数据那么必然就会有读取数据
1.lord_workbook
wb = load_workbook('红牛.xlsx') print(wb.sheetnames) # ['红牛信息', 'Sheet'] # 查看excel表格中所有工作簿的名称 结果是一个表格
2.取值
print(wb1.max_row) # 41 获取最大的行数 print(wb1.max_column) # 4 获取最大列数 # 第一种取值方式 print(wb1['A1']) # <Cell '红牛信息'.A1> 可以准确获取表格是把哪个数据 # 第二种取值方式 print(wb1.cell(row=2, column=2).value) # 杭州市上城区庆春路29号远洋大厦11楼A座 可以通过行数和列数获取数据 ''' openpyxl模块其实是不擅长读取数据的 所以一些模块优化了读取方式 那就是pandas模块 '''
random模块
random模块又称之为随机模块
random模块时一个很好玩的模块
1.random()
import random print(random.random())
# 每次运行都会随机产生一个0-1的小数(不包括0和1)
2.randint()
import random print(random.randint(0, 6)) # 每次运行都会随机产生一个0到6之间的一个整数(包括0和6) 0和6可以是任意数
3.choice()
print(random.choice(['特等奖', '一等奖', '二等奖', '三等奖'])) # 每次运行都会在列表中随机抽取一个数
4.sample()
import random print(random.sample(['特等奖', '一等奖', '二等奖', '三等奖', '安慰奖', '参与奖'], 2)) # ['参与奖', '安慰奖'] # 每次运行都会在列表中随机抽取两个数 print(random.sample(['特等奖', '一等奖', '二等奖', '三等奖', '安慰奖', '参与奖'], 3)) # ['三等奖', '一等奖', '参与奖'] # 每次运行都会在列表中随机抽取三个数 # 可自定义一个抽取数
5.shuffle()
import random l1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A'] random.shuffle(l1) print(l1) # [7, 8, 'J', 10, 6, 'K', 4, 9, 2, 'Q', 3, 'A', 5] # shuffle 每次运行都会把传入的容器里的数据打乱
6.小小面试题
# 随机产生五位数的验证码(数字、大写字母、小写字母) import random # code = '' # random_num = str(random.randint(0, 9)) # random_upper = chr(random.randint(65, 90)) # random_lower = chr(random.randint(97, 122)) # for i in range(5): # temp_code = random.choice([random_num, random_lower, random_upper]) # code += temp_code # print(code) # CC7mC
# 我们还可以把这个功能封装成函数 def get_code(n): code = '' random_num = str(random.randint(0, 9)) random_upper = chr(random.randint(65, 90)) random_lower = chr(random.randint(97, 122)) for i in range(n): temp_code = random.choice([random_num, random_lower, random_upper]) code += temp_code return code res = get_code(6) print(res) # q11Xqq # 这样我们就可以任意产生几位数的验证码
hashlib加密模块
1.什么是加密
就是把明文数据(看得懂的)经过处理后变成密文数据(看不懂的)
2.为什么要加密
不想让敏感数据轻易的泄露
3.如何判断数据是否已经加密
一般情况下看到一串没有规则的数字字母符号组合一般都是加密过后的结果
4.如何加密
加密在计算机中是要通过加密算法的
就是对明文数据采用的机密策略
不同的加密算法的复杂程度不一样 得出的结果也会不一样
通常情况下机密之后的结果越长 说明采用的加密算法越复杂
5.常见的加密算法
md5 sha系列 hmac base64
1.加密代码体现
import hashlib md5 = hashlib.md5() # 选择md5算法作为数据的加密策略 md5.update(b'123') # 往里面添加明文数据 数据必须是bytes类型 res = md5.hexdigest() # 获取加密之后的数据 print(res) # 202cb962ac59075b964b07152d234b70 md5.update(b'jason') res1 = md5.hexdigest() print(res1) # 65a2eab1aaca6a9aa2a0e9d58ee20f36
2.加密补充
1.一般情况下机密之后的密文是不能反解密的
加密之后只有使用者知道自己加密的数据
所谓的反解密都是在偷换概念
就是我们可以提前假设别人的密码是什么 然后在通过算法得出密文
之后在够着对应关系 然后对比密文 之后就可以得出明文
2.只要明文数据是一样的那么采用相同的算法得出的密文也是一样的
import hashlib md5.update(b'123') md5.update(b'hello') md5.update(b'jason') res = md5.hexdigest() print(res) # 31b9a81dc788368469ee4b78877eb1eb md5.update(b'123hellojason') res1 = md5.hexdigest() print(res1) #31b9a81dc788368469ee4b78877eb1eb # 不管你是分几次传入还是一次传入 只要明文数据是一样的那么密文肯定是一样的
3.加盐处理
就是可以加入干扰项 可以不会那么任意泄露数据
import hashlib md5.update('公司设置的盐(干扰项)'.encode('utf8')) # 明文数据必须是二进制 md5.update(b'123hellojason') res1 = md5.hexdigest() print(res1) # b68946fd2bb01cc03c6c5fc4fc062f14 # 就是把干扰项跟真是数据一起加密 不容易泄密
4.动态加盐
import datetime import hashlib md5 = hashlib.md5() res = datetime.datetime.today() # 2022-07-21 19:19:33.731568 res = str(res) print(res) md5.update(res.encode('utf8')) md5.update(b'jason') res1 = md5.hexdigest() print(res1) # b9e3ef9e09245f4a572da03fbdb77906 # 我们可以动态获取当前时间然后在跟真实数据一起加密这样会相较于普通的加盐会更安全一些 # 还可以获取用户名时截取用户名的一段 #这样每次加盐都不一样会更安全一些
5.加密的实际引用场景
1.用户密码加密
用户注册时对用户的密码加密然后保存
然后登入的时候也是对用户登入的密码进行加密
然后对两个密文进行对比
2.文件安全性校验
正规的软件写完后会对程序进行加密
网址提供软件文件记忆改文件内容对应的密文
用户下载后不会立马执行软件 会先进行对内容加密
然后对比对比两次密文是否一致 如果一致那么表示文件内容没有被改动
如果不一致那么说明有可能被植入病毒
3.大文件加密优化
一般情况下如果家买文件是很大的话 那么直接加密速度会很慢 (100G)
我们可以不对100G直接加密 可以截取一段进行加密
每隔500M读取30bytes
subprocess模块
模拟计算机cmd窗口
import subprocess cmd = input('请输入您的指令>>>:').strip() sub = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) # stdout执行命令之后正确的返回结果 print(sub.stdout.read().decode('gbk')) # stderr执行命令报错之后的返回结果 print(sub.stderr.read().decode('gbk'))
日志模块
1.什么日志
日志就是类似于记录历史记录
2.为什么要有日志
记录事物发生的事实
3.如何使用日志
3.1 日志的等级
import logging logging.debug('debug等级') # 10 logging.info('info等级') # 20 logging.warning('warning等级') # 30 默认日志是从warning级别开始记录的 logging.error('error等级') # 40 logging.critical('critical等级') # 50 # 还可以使用数字代表那个等级
3.2基本使用
import logging file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8', ) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', handlers=[file_handler, ], level=logging.ERROR ) # 上面都是创建日志格式和等级 logging.error('我不好!!!') # 记录日志信息
日志的组成部分
import logging # 1.日志的产生(准备原材料) logger对象 logger = logging.getLogger('购物车记录') # 2.日志的过滤(剔除不良品) filter对象>>>:可以忽略 不用使用 # 3.日志的产出(成品) handler对象 hd1 = logging.FileHandler('a1.log', encoding='utf-8') # 输出到文件中 hd2 = logging.FileHandler('a2.log', encoding='utf-8') # 输出到文件中 hd3 = logging.StreamHandler() # 输出到终端 # 4.日志的格式(包装) format对象 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.addHandler(hd1) logger.addHandler(hd2) logger.addHandler(hd3) # 6.给handler绑定formmate对象 hd1.setFormatter(fm1) hd2.setFormatter(fm2) hd3.setFormatter(fm1) # 7.设置日志等级 logger.setLevel(10) # debug # 8.记录日志 logger.debug('写了半天 好累啊 好热啊') """ 我们在记录日志的时候 不需要向上述一样全部自己写 过于繁琐 所以该模块提供了固定的配置字典直接调用即可 """
日志字典
import logging 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_path = 'a3.log' # 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, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置 # '购物车记录': { # 'handlers': ['default','console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 # 'level': 'WARNING', # 'propagate': True, # 向上(更高level的logger)传递 # }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置 }, } logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置 logger1 = logging.getLogger('红浪漫顾客消费记录') # 写入日志信息 logger1.debug('慢男 猛男 骚男') # 写入日志内容