模块介绍(三)
模块介绍(三)
openpyxl读取数据
1.创建一个新的xlsx表格
import openpyxl
from openpyxl import Workbook #首先调用Workbook模块
wb = Workbook()
wb1 = wb.create_sheet('刘瑞奇富婆电话薄')
wb2 = wb.create_sheet('谢国贤洗浴中心技师合集')
wb3 = wb.create_sheet('翁志豪养老协会')
2.给表格填充一些数据
wb1.append(['username', 'password', 'age', 'gender', 'hobby'])
wb1.append(['joseph1', 123, 18, 'male', 'read'])
wb1.append(['joseph2', 123, 21, 'male', 'read'])
wb1.append(['joseph3', 123, 39, 'male', 'read'])
wb1.append(['joseph4', 123, 52, 'male', 'read'])
wb1.append(['joseph4', 123, 88, 'male', None])
wb1.append([None, 123, 103, 'male', ''])
wb.save(r'one.xlsx')
3.查看内部的数据
from openpyxl import Workbook, load_workbook
wb = load_workbook(r'one.xlsx', data_only=True)
print(wb1.max_row) # 打印有多少行数据,以便我们查看数据
print(wb1.max_column) # 打印列有多少个数据,方便我们查看数据
print(wb1.cell(row=2, column=3).value) # 获取某个固定位置的值直接显示
4.循环打印行和列
for i in wb1.rows:
print([k.value for k in i]) # 循环打印行
for i in wb1.columns:
print(k.value.next() for k in i) # 循环打印列
random随机模块
1.随机模块
import random
# print(random.random()) # 返回一串0-1之间随机的浮点数0.6176736839224983
random.seed()
print('使用种子生成随机数:',random.random())
print(random.randint(1, 8)) # 随机抽取一个你所自定义的数字区间中的一个数字 4
print(random.choice(['佐伊', '霞', '阿狸', '卡莎', '戴安娜', '日女'])) # 随机抽取一个你所定义的内容 戴安娜
print(random.sample(['特朗普', '拜登', '希拉里', '布林肯', '沙利文', '蓬佩奥', '福山', '乔治凯南'], 2)) # 随机收取一组你所定义的内容,并且内部数量你也可以定义
l1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A', 'alex', 'joker'] # 创建一个列表
print(random.shuffle(l1)) # 随机在列表中抽取一个数,性感荷官在线发牌
2.验证码
def func(n): # 设置一个函数
count = '' # 定义一个存储器
for i in range(n): # 循环给的数据
random_int = str(random.randint(0, 9)) # 随机出现0-9之间的数据
random_lower = chr(random.randint(65, 90)) # 随机出现ASCII编码中的65位到九十位
random_upper = chr(random.randint(97, 122)) # 随机出现ASCII编码中97位到一百二十二位
temp = random.choice([random_int, random_lower, random_upper]) # 将三个数据都放入随机选择中
count += temp # 将循环出来的存入全局定位
return count # 返回全局定位
res = input('请输入您需要出现的随机数位数>>>:') # 获取输入
res = int(res) # 转为数字,其实应该判断来着,懒
res1 = func(res) # 再赋值一次
print(res1) # 打印
random 模块方法
random 模块方法如下:
方法 | 描述 |
---|---|
seed() | 初始化随机数生成器 |
getstate() | 返回捕获生成器当前内部状态的对象。 |
setstate() | state 应该是从之前调用 getstate() 获得的,并且 setstate() 将生成器的内部状态恢复到 getstate() 被调用时的状态。 |
getrandbits(k) | 返回具有 k 个随机比特位的非负 Python 整数。 此方法随 MersenneTwister 生成器一起提供,其他一些生成器也可能将其作为 API 的可选部分提供。 在可能的情况下,getrandbits() 会启用 randrange() 来处理任意大的区间。 |
randrange() | 从 range(start, stop, step) 返回一个随机选择的元素。 |
randint(a, b) | 返回随机整数 N 满足 a <= N <= b。 |
choice(seq) | 从非空序列 seq 返回一个随机元素。 如果 seq 为空,则引发 IndexError。 |
choices(population, weights=None, *, cum_weights=None, k=1) | 从 population 中选择替换,返回大小为 k 的元素列表。 如果 population 为空,则引发 IndexError。 |
[shuffle(x, random]) | 将序列 x 随机打乱位置。 |
sample(population, k, *, counts=None) | 返回从总体序列或集合中选择的唯一元素的 k 长度列表。 用于无重复的随机抽样。 |
random() | 返回 [0.0, 1.0) 范围内的下一个随机浮点数。 |
uniform() | 返回一个随机浮点数 N ,当 a <= b 时 a <= N <= b ,当 b < a 时 b <= N <= a 。 |
triangular(low, high, mode) | 返回一个随机浮点数 N ,使得 low <= N <= high 并在这些边界之间使用指定的 mode 。 low 和 high 边界默认为零和一。 mode 参数默认为边界之间的中点,给出对称分布。 |
betavariate(alpha, beta) | Beta 分布。 参数的条件是 alpha > 0 和 beta > 0。 返回值的范围介于 0 和 1 之间。 |
expovariate(lambd) | 指数分布。 lambd 是 1.0 除以所需的平均值,它应该是非零的。 |
gammavariate() | Gamma 分布( 不是伽马函数) 参数的条件是 alpha > 0 和 beta > 0。 |
gauss(mu, sigma) | 正态分布,也称高斯分布。 mu 为平均值,而 sigma 为标准差。 此函数要稍快于下面所定义的 normalvariate() 函数。 |
lognormvariate(mu, sigma) | 对数正态分布。 如果你采用这个分布的自然对数,你将得到一个正态分布,平均值为 mu 和标准差为 sigma 。 mu 可以是任何值,sigma 必须大于零。 |
normalvariate(mu, sigma) | 正态分布。 mu 是平均值,sigma 是标准差。 |
vonmisesvariate(mu, kappa) | 冯·米塞斯分布。 mu 是平均角度,以弧度表示,介于0和 2pi 之间,kappa 是浓度参数,必须大于或等于零。 如果 kappa 等于零,则该分布在 0 到 2pi 的范围内减小到均匀的随机角度。 |
paretovariate(alpha) | 帕累托分布。 alpha 是形状参数。 |
weibullvariate(alpha, beta) | 威布尔分布。 alpha 是比例参数,beta 是形状参数。 |
hashlib加密模块
1.什么是加密
加密本质上就是将一些我们一眼就可以看的懂的明文转成一段随机出现的编码,这样就可以尽量避免我们的私密信息遭到泄露,我们再对比的时候只需要对比是否是这段加密编码就好了
2.如何判断加密
一般情况下如果是一串没有任何顺序的编码组合在一起那么它可能就是加密代码
常见的加密代码有:md5, sha系列, hmac, base64
3.加密算法的本质
加密算法其实就是将一段明文给她一段随机生成的编码就算是加密,对加密来说一般越长的加密段他的加密等级就越高
加密等级
薄弱(Weak)O(2 40),
传统(Legacy)O(2 64),
基准(Baseline)0(2 80),
标准(Standard)O(2 128),
较高(High)O(2 192),
超高(Ultra)O(2 256),
4.加密代码
import hashlib # 首先我们调用哈希模块
md5 = hashlib.md5() # 将md5赋值一个加密模式
md5.update(b'joseph') # 给md5一个需要加密的数据
res = md5.hexdigest() # 赋值,并打印
print(res) # cb07901c53218323c4ceacdea4b23c98
加密算法补充说明
1.解密的概念
解密其实大多数的时候都是偷换概念,提前假设一下别人的密码然后,猜测对方加密算法的样式比对对应关系来测试是否是你的密码,然后返还给你
2.明文算法数据是一样的无论它怎么加他得到的算法密文都是固定的
import hashlib # 调用模块
md5 = hashlib.md5() # 创造一个hashlib
md5.update(b'joseph') # 添加内容必须是bytes模式
md5.update(b'trump')
md5.update(b'520')
res = md5.hexdigest()
print(res) # 73faca6bdd3261e268927b2632d1808f
md5.update(b'josephtrump520') # 合在一起
res = md5.hexdigest() # 赋值
print(res) # 73faca6bdd3261e268927b2632d1808f
3.加盐加密(师傅打个盐,再打个蜂蜜,不要玫瑰精油和搓泥宝)
import hashlib # 调用模块
password = input('请输入您的密码>>>:').strip() # 520
md5 = hashlib.md5() # 加密赋值
md5.update('干扰项'.encode('utf8')) # 选择加盐项
md5.update(password.encode('utf8')) # 将密码进行加密
res = md5.hexdigest() # 赋值
print(res) # 790702a687e108d73d5b3d1a926a6a9d
4.动态打盐
动态打盐其实就是将现在的时间或者用户名的一部分给密码当作打盐项实现每个都不一样的动态打盐
import time
import hashlib # 调用模块
time_num = time.strftime("%Y-%m-%d %H:%M:%S %p") # 获取当前时间
# print(time_num)
password = input('请输入您的密码>>>:').strip() # 520
md5 = hashlib.md5() # 加密赋值
md5.update(time_num.encode('utf8')) # 选择加盐项,将现在的时间当作盐加进去
md5.update(password.encode('utf8')) # 将密码进行加密
res = md5.hexdigest() # 赋值
print(res) # 747cf2e7638c1c34b78df8e253131739
5.加密实际应用场景
1.用户密码加密
注册存储密文 登录也是比对密文
2.文件安全性校验
正规的软件程序写完之后做一个内容的加密
网址提供软件文件记忆该文件内容对应的密文
用户下载完成后不直接运行 而是对下载的内容做加密
然后比对两次密文是否一致 如果一致表示文件没有被改
不一致则表示改程序有可能被植入病毒
3.大文件加密优化
程序文件100G
一般情况下读取100G内容然后全部加密 太慢
不对100G所有的内容加密 而是截取一部分加密
eg:每隔500M读取30bytes
subprocess模块
1.subprocess模块
import subprocess
cmd = input('请输入你的指令>>>:').strip()
sub = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
print(sub.stdout.read().decode('gbk'))
print(sub.stderr.read().decode('gbk'))
2.应用
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
cwd:用于设置子进程的当前目录。
env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。
日志模块简介
1.什么是日志
日志其实就是对于历史的记录,为了记录这个事实的发生,供以后来参考,就像以前的史官无论君王用多么残忍的手段对付史官,史官也不愿意去修改已经发生的事情,对于后世的负责,对自己的负责。
2.日志的等级
import logging
logging.debug('debug等级') # 10
logging.info('info等级') # 20
logging.warning('warning等级') # 默认从warning级别开始记录日志 30
logging.error('error等级') # 40
logging.critical('critical等级') # 50
3.日志模拟
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('累死了') # 日志报错
日志的重要组成部分
1.书写多层日志并返回给客户端
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('MAGA,骄傲男孩') # 最后输出
"""
记录日志的时候我们一般直接调用模块写就行,一般不需要像上方一样盖个设置调用和输出地址等
"""
日志结合软件开发目录规范的使用
# 按照软件开发目录规范编写使用
日志字典数据应该放在哪个py文件内
字典数据是日志模块固定的配置 写完一次之后几乎都不需要动
它属于配置文件
"""配置文件中变量名推荐全大写"""
该案例能够带你搞明白软件开发目录规范中所有py文件的真正作用
def get_logger(msg):
# 记录日志
logging.config.dictConfig(settings.LOGGING_DIC) # 自动加载字典中的配置
logger1 = logging.getLogger(msg)
# logger1.debug(f'{username}注册成功') # 这里让用户自己写更好
return logger1
日志的模板
1.日志模板
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)