python 6
collections模块
包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择;
1.namedtuple(具名元组)
from collections import namedtuple
'''可以创建包含名称的tuple'''
point = namedtuple('坐标',['x','y'])
# 调用了namedtuple的元组对象
p1 = point(1,2)
p2 = point(10,8)
print(p1,p2) # 坐标(x=1, y=2) 坐标(x=10, y=8)
print(p1.x) # 1
print(p1.y) # 2
person = namedtuple('人物','name age gender')
# 调用了namedtuple的元组对象
p1 = person('jason',18,'male')
p2 = person('kevin',28,'female')
print(p1,p2)
# 人物(name='jason', age=18, gender='male') 人物(name='kevin', age=28, gender='female')
print(p1.name,p1.age) # jason 18
"""具名元组的使用场景也非常的广泛 比如数学领域、娱乐领域等"""
card = namedtuple('扑克牌', ['花色', '点数'])
c1 = card('黑桃♠', 'A')
c2 = card('黑梅♣', 'K')
c3 = card('红心❤', 'A')
print(c1, c2, c3)
print(c1.点数)
2.deque(双端队列)
from collections import deque
'类似于list的容器,可以快速的在队列头部和尾部添加、删除元素'
q = deque([1,2,3])
print(q)
q.append(444) # 右边添加元素
print(q)
q.appendleft(666) # 左边添加元素
print(q)
q.pop() # 右边弹出元素
q.popleft() # 左边弹出元素
3.OrderedDict(有序字典)
from collections import OrderedDict
'dict的子类,可以记住元素的添加顺序'
from collections import OrderedDict
d2 = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(d2)
# OrderedDict([('a', 1), ('b', 2), ('c', 3)])
d2['x'] = 111
d2['y'] = 222
d2['z'] = 333
print(d2)
# OrderedDict([('a', 1), ('b', 2), ('c', 3), ('x', 111), ('y', 222), ('z', 333)])
print(d2.keys())
# odict_keys(['a', 'b', 'c', 'x', 'y', 'z'])
4.defaultdict(含默认值字典)
'dict的子类,可以调用提供默认值的函数'
from collections import defaultdict
values = [11, 22, 33,44,55,67,77,88,99,90]
my_dict = defaultdict(list) # 字典所有的值默认都是列表
for value in values:
if value>66:
my_dict['k1'].append(value)
else:
my_dict['k2'].append(value)
5.Counter(hash对象计数)
'dict的子类,计算可hash的对象'
from collections import Counter
r = Counter(res)
print(r) # Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
print(r.get('a')) # 可以当成字典使用
time模块
1.常用方法
1.time.sleep(secs)
推迟指定的时间运行,单位为秒
2.time.time()
获取当前时间戳
2.三种用于表示时间的格式(彼此之间可以转换)
timestamp(时间戳)
距离1970年1月1日0时0分0秒至此相差的秒数
time.time()
struct_time(结构化时间)
time.localtime()
属性 值
tm_year(年) 比如2011
tm_mon(月) 1 - 12
tm_mday(日) 1 - 31
tm_hour(时) 0 - 23
tm_min(分) 0 - 59
tm_sec(秒) 0 - 61
tm_wday(weekday) 0 - 6(0表示周日)
tm_yday(一年中的第几天) 1 - 366
tm_isdst(是否是夏令时) 默认为-1
format time(格式化时间)
人最容易接收的一种时间格式 2000/1/21 11:11:11
time.strftime()
'%Y-%m-%d %H:%M:%S' # 2022-03-29 11:31:30
'%Y-%m-%d %X' # 2022-03-29 11:31:30
格式 | 含义 |
---|---|
%a | 本地(locale)简化星期名称 |
%A | 本地完整星期名称 |
%b | 本地简化月份名称 |
%B | 本地完整月份名称 |
%c | 本地相应的日期和时间表示 |
%d | 一个月中的第几天(01 – 31) |
%H | 一天中的第几个小时(24小时制,00 – 23) |
%I | 第几个小时(12小时制,01 – 12) |
%j | 一年中的第几天(001 – 366) |
%m | 月份(01 – 12) |
%M | 分钟数(00 – 59) |
%p | 本地am或者pm的相应符 |
%S | 秒(01 – 61) |
%U | 一年中的星期数。(00 – 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。 |
%w | 一个星期中的第几天(0 – 6,0是星期天) |
%W | 和%U基本相同,不同的是%W以星期一为一个星期的开始。 |
%x | 本地相应日期 |
%X | 本地相应时间 |
%y | 去掉世纪的年份(00 – 99) |
%Y | 完整的年份 |
%Z | 时区的名字(如果不存在为空字符) |
%% | ‘%’字符 |
3.时间类型的转换
格式化时间 <==> 结构化时间 <==> 时间戳
format time struct_time timestamp
# 时间戳<-->结构化时间
gmtime
localtime
# 结构化时间<-->格式化时间
strftime
strptime
time.strptime("2017-03-16","%Y-%m-%d")
time.strptime("2017/03","%Y/%m") 前后必须一致
ps:UTC时间比我所在的区域时间早八个小时(时区划分)
datetime模块
'datatime模块重新封装了time模块,提供更多接口,提供的类有:date,time,datetime,timedelta,tzinfo。'
import datetime
1.date
date.today() # 返回一个表示当前本地日期的date对象;年月日
res = datetime.date.today()
print(res.year) # 2022
print(res.month) # 3
print(res.day) # 29
print(res.weekday()) # 1 星期0-6
print(res.isoweekday()) # 2 星期1-7
2.datetime
datetime.today() # 返回一个表示当前本地时间的datetime对象;年月日 时分秒
3.timedelta
'使用timedelta可以很方便的在日期上做天days,小时hour,分钟,秒,毫秒,微妙的时间计算。'
print('microseconds:', datetime.timedelta(microseconds=1)) #microseconds: 0:00:00.000001
print('milliseconds:', datetime.timedelta(milliseconds=1)) #milliseconds: 0:00:00.001000
print('seconds :', datetime.timedelta(seconds=1)) #seconds : 0:00:01
print('minutes :', datetime.timedelta(minutes=1)) #minutes : 0:01:00
print('hours :', datetime.timedelta(hours=1)) #hours : 1:00:00
print('days :', datetime.timedelta(days=1)) #days : 1 day, 0:00:00
print('weeks :', datetime.timedelta(weeks=1)) #weeks : 7 days, 0:00:00
"""
针对时间计算的公式
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
"""
random模块
'''随机数模块'''
import random
print(random.random()) # 随机产生一个0到1之间的小数
print(random.uniform(2, 4)) # 随机产生一个2到4之间的小数
print(random.randint(0, 9)) # 随机产生一个0到9之间的整数(包含0和9)
print(random.randint(1, 6)) # 掷骰子
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
random.shuffle(l) # 随机打乱一个数据集合 洗牌
print(l)
ll1 = ['特等奖', '张飞抱回家', '如花', '百万现金大奖', '群内配对']
print(random.choice(ll1)) # 随机抽取一个 抽奖
os模块
"""该模块主要是跟操作系统打交道"""
import os
1.创建目录(文件夹)
os.mkdir(r'aaa') # 使用相对路径 在当前执行文件所在的路径下创建一个aaa文件夹
os.mkdir(r'bbb/ccc') # mkdir只能创建单级目录
os.makedirs(r'ccc') # makedirs可以创建单级目录
os.makedirs(r'bbb/ccc/ddd') # makedirs支持创建多级目录
2.删除目录(文件夹)
os.rmdir(r'aaa') # 可以删除单级目录
os.rmdir(r'bbb') # 只能删空的单级目录
os.removedirs(r'ccc') # 可以删除单级目录
os.removedirs(r'/Users/jiboyuan/PycharmProjects/day21/bbb/ccc/ddd') # 删除目录之后如果外层的目录也是空的则继续删除
3.查看某个路径下所有的文件名称(文件、文件夹)
print(os.listdir())
print(os.listdir(r'/Users'))
4.删除文件、重命名文件
os.remove(r'a.txt')
os.rename(r'a.txt', r'aaa.txt')
5.获取当前路径、切换路径
print(os.getcwd())
os.chdir(r'/Users/jiboyuan')
print(os.getcwd())
6.软件开发目录规范 启动脚本兼容性操作
os.path.dirname(__file__) # 动态获取当前执行文件所在的绝对路径 D:\day21
os.path.dirname(os.path.dirname(__file__)) # 每嵌套一层就是往上切换一层 D:\
print(os.path.abspath(__file__)) # 动态获取当前执行文件自身的路径 D:\day21\a.py
7.判断文件是否存在
print(os.path.exists(r'ATM')) # True 判断所给的路径是否存在
print(os.path.exists(r'01 作业讲解.py')) # True 判断所给的路径是否存在
print(os.path.isdir(r'ATM')) # True 判断路径是否是一个文件夹
print(os.path.isdir(r'01 作业讲解.py')) # False 判断路径是否是一个文件夹
print(os.path.isfile(r'ATM')) # False 判断路径是否是一个文件
print(os.path.isfile(r'01 作业讲解.py')) # True 判断路径是否是一个文件
8.拼接路径(极容易忽略)
base_dir = 'ATM'
exe_dir = '01 作业讲解.py'
'''拼接成py文件的路径'''
print(base_dir + '/' + exe_dir) # 路径分隔符在不同的系统下是不一样的 使用加号的话兼容性极差
res = os.path.join(base_dir, exe_dir) # 能够自动识别当前操作系统的分隔符
print(res)
9.获取文件大小(字节 bytes)
print(os.path.getsize(r'ATM')) # 128bytes
print(os.path.getsize(r'a.txt')) # 14bytes
sys模块
"""该模块主要是跟python解释器打交道"""
import sys
1.列举当前执行文件所在的sys.path(掌握)
print(sys.path)
2.获取解释器版本信息(了解)
print(sys.version)
3.获取平台信息(了解)
print(sys.platform)
4.自定义命令行操作
print(sys.argv)
"""
cmd终端可以使用windows+r并输入cmd唤起
也可以在pycharm直接使用快捷方式Terminal
模拟cmd并自动切换到当前执行文件所在的路径下
"""
json模块
'''json是一个序列化模块 主要用于跨语言传输数据'''
1.参考群内截图得知json格式数据是不同变成语言之间数据交互的媒介
2.json格式数据的具体特征
结论1中有一个小细节>>>:数据基于网络传输肯定是二进制格式
在python中bytes类型的数据可以直接看成是二级制数据
python中哪些数据可以转成bytes类型(编码encode())
只有字符串可以!!!
# 由上述推论可知 json格式数据 本质应该属于字符串类型
import json
d = {'username':'jason','pwd':123}
print(d, type(d)) # {'username': 'jason', 'pwd': 123} <class 'dict'>
res = json.dumps(d)
print(res, type(res)) # {"username": "jason", "pwd": 123} <class 'str'>
print(str(d),type(str(d))) # {'username': 'jason', 'pwd': 123} <class 'str'>
'''双引号是json格式数据独有的标志符号'''
d = {"username":"jason","pwd":123}
print(d) # {'username': 'jason', 'pwd': 123} 不是json格式
res1 = '{"username":"jason","pwd":123}'
print(res1) # {"username":"jason","pwd":123} 算json格式
序列化与反序列化
"""
json.dumps() 序列化
将python数据类型转换成json格式字符串
json.loads() 反序列化
将json格式字符串转换成对应的数据类型
如果json模块需要配合文件一起使用的话 有固定的方法
json.dump()
将其他数据类型直接写入文件(自动转json格式字符串)
json.load()
将文件数据直接转成对应的数据类型(自动反序列化)
"""
不是所有的数据类型都支持序列化
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float | number |
True | true |
False | false |
None | null |
集合
不支持序列化
pickle模块
# 基本不用
因为它不支持跨语言传输 只能识别python代码
'''直接忽略 不用掌握'''
subprocess模块
import subprocess
# ls在终端的意思就是查看当前路径下所有的文件名称
res = subprocess.Popen('ls',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
print('stdout',res.stdout.read().decode('utf8')) # 获取正确命令执行之后的结果
print('stderr',res.stderr.read().decode('utf8')) # 获取错误命令执行之后的结果
"""
该模块可以实现远程操作其他计算机的功能
动态获取命令执行并返回结果
eg:类似于Xshell软件的功能
"""
hashlib加密模块
"""加密模块"""
# 什么是加密
将明文(人看得懂)数据通过一些手段变成密文数据(人看不懂)
密文数据的表现形式一般都是一串没有规则的字符串
# 加密算法
加密算法有很多种>>>(将明文变密文的内部规则)
算法的难易程度可以根据产生密文的长短来判断
越长意味着算法越复杂
# 什么时候使用加密
涉及到隐私数据的时候 应该考虑使用加密
最为常见的就是对用户的密码加密 防止密码泄露
import hashlib
1.基本使用
1.指定算法
'md5算法(最为常见 一般的业务需求足够了)'
md5 = hashlib.md5()
2.将明文数据传递给算法对象
md5.update(b'hello') # 只能接收bytes类型
"""如果字符串中是纯数字和英文 那么直接在前面加b转成bytes类型"""
3.获取加密之后的密文数据
res = md5.hexdigest()
print(res) # 5d41402abc4b2a76b9719d911017c592
在传入数据的时候 只要内容一致 那么算法的结果肯定一致
'比如一次性传入 hello 和 第一次传入he 第二次传入llo的密文是一样的'
2.加密补充
1.加密之后的结果是无法直接反解密的
8faebe82e744992e51c86845cac3e1b7
# 所谓的反解密其实是暴力破解>>>:反复的猜
"""
md5解密内部本质
提前想好很多可能是密码的组合
123 自己加密
321 自己加密
222 自己加密
{'密文1':123,'密文2':321}
"""
2.加盐处理
增加破解的难度
import hashlib
md5 = hashlib.md5()
# 加盐处理(添加一些额外的干扰项)
md5.update('你追我'.encode('utf8'))
md5.update(b'123')
print(md5.hexdigest()) # ce850e70febde5f3506fec0479dc0f96
3.动态加盐
干扰项动态变化
可以是用户名的一部分 也可以当前时间...
"""
加密应用场景
1.密码加密如何比对
用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文
之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误
2.文件内容一致性校验
作为软件的提供者 我们在提供安全软件的同时会对给该软件内容做加密处理得到一个该安全软件独有的密文
用户在下载软件之后也会对内容做相同的加密之后比对两次密文是否一致
如果是表示中途没有被修改 如果不是表示中途被修改过 可能存在病毒
"""
针对大文件一致性校验的优化策略
如果一个文件有10G 那么如果全部读取并加密速度太慢
这个时候可以考虑对文件内容进行切片读取并加密的操作
logging模块
'''日志模块就是在程序的各个环境记录 便于后续的查看'''
# 针对日志模块 我们只需要听流程思路 最后CV即可 无需详细记忆
# 1.日志等级
import logging
# 日志按照重要程度分为五个级别:默认只有达到warning警告级别及以上才会记录日志
# logging.debug('debug message') # 10
# logging.info('info message') # 20
# logging.warning('warning message') # 30
# logging.error('error message') # 40
# logging.critical('critical message') # 50
# 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
)