昨日内容回顾
自定义模块
模块的两种执行方式
‘__name__’ ‘__file__’’__all__’
模块导入的多种方式
相对导入
random:
random.random():
random.uniform():
random.randint(a,b):
random.shuffle(x):
random.sample(x,k):
今日内容
常用模块的介绍:
time(时间相关),datetime(日期时间相关)
os,sys
hashilb(加密相关),json(序列化相关),pickle,collections(集合相关)
time:和时间相关
封装了获取时间戳和字符串形式的时间的一些方法
"""
time 模块
三大对象:
时间戳
结构化时间对象(9大对象)
字符串
"""
import time
# 获取时间戳
# 时间戳:从时间元年(1970/01/01 00:00:00)到现在经过的秒数
# print(time.time())
# 获取格式化时间对象:是九个字段组成的
# 默认参数是当前系统时间的时间戳
# print(time.gmtime())# 格林尼治时间
# print(time.localtime())# 当地时间
# print(time.gmtime(1))# 时间元年过一秒后,对应的时间对象
# 时间对象->时间戳
# t1 = time.localtime()# 时间对象
# t2 = time.mktime(t1)# 获取对应的时间戳
# print(t2)
# print(time.mktime(time.localtime()))
# 格式化时间对象和字符串之间的转换
# s = time.strftime('%Y %m %d %H:%M:%S')
# print(s)# 2020 07 23 08:49:10
#
# s1 = time.strftime('%y %m %d %H:%M:%S')
# print(s1)# 20 07 23 08:51:55
# 吧时间字符串转换成时间对象
# time_obj = time.strptime('2010 10 10','%Y %m %d')
# print(time_obj)
# 暂停当前程序,睡眠xxx秒
# time.sleep(xxx)
# for i in range(5):
# print(time.strftime('%Y-%m-%d %H:%M:%S'))
# # 休眠
# time.sleep(1)
datetime:日期时间模块
"""
datetime:日期时间模块
date
time
datetime
timedelta
"""
import datetime
# date类:
# d = datetime.date(2010,10,10)
# print(d)
# 获取date对象的各个属性
# print(d.year)
# print(d.month)
# print(d.day)
# time类:
# t = datetime.time(9,28,59)
# print(t)
# # time类的属性
# print(t.hour)
# print(t.minute)
# print(t.second)
# datetime
# dt = datetime.datetime(2019,12,17,0,0,0)
# print(dt)
# datetime中的类,主要用于数学计算
# timedelta:时间的变化量(可加可减)
# td = datetime.timedelta(days=2)
# print(td)# 2 days, 0:00:00
# # 参与数学运算
# # 创建时间对象:
# # date,datetime,timedelta,只能和这三类进行数学运算
# d = datetime.date(2008,8,8)
# res = d + td
# print(res)# 2008-08-10
# 时间变化量的计算是否会产生进位
# t = datetime.datetime(2009,2,3,10,59,59)
# td = datetime.timedelta(seconds=1)
# res = t+td
# print(res)
# 练习:计算某一年的二月份有几天
# a = datetime.date(2974,3,1)
# b = datetime.timedelta(days = 1)
# res = a-b
# print(f'{res}是平年')
# year = int(input('请输入'))
# d = datetime.date(year,3,1)
# oneday = datetime.timedelta(days = 1)
# res = d-oneday
# print(res.day)
# timedelta和时间段进行运算的结果的类型???和另一个操作数保持一致
# a = datetime.date(2974,3,1)# <class 'datetime.date'>
# a = datetime.datetime(2009,2,3,10,59,59)# <class 'datetime.datetime'>
# a = datetime.timedelta(seconds = 1)# <class 'datetime.timedelta'>
# b = datetime.timedelta(days = 1)
# res = a-b
# print(type(res))
os模块
"""
os:和操作系统相关的操作被封装到这个模块中
"""
# 和文件操作相关:重命名,删除
import os
# os.remove('a')
# os.rename('a','b')
# 删除目录,必须是空目录
# os.removedirs('aa')
# 使用shutil模块,删除带内容的目录
# import shutil
# shutil.rmtree('aa')
# 和路径相关的操作,被封装到另一个子模块中:os.path
# res = os.path.dirname(r'd:/aaa/bbb/ccc/a')
# # 不判断路径是否存在
# print(res)
# 获取文件名
# res = os.path.basename(r'd:/aaa/bbb/ccc/a')
# print(res)
# 把路径中路径名和文件名切分开,结果是元组tuple
# res = os.path.split(r'd:/aaa/bbb/ccc/a')
# print(res)
# 路径拼接
# res2 = os.path.join('d:/','aaa','bbb','ccc')
# res3 = os.path.join('d:\\','aaa','bbb','ccc')
# print(res3)# d:\aaa\bbb\ccc
# print(res2)# d:/aaa\bbb\ccc
# 如果是/开头的路径,默认是在当前盘符下
# res = os.path.abspath(r'd:/a/b/c')
# print(res)
# res2 = os.path.abspath(r'/a/b/c')
# print(res2)
# # 如果不是以/开头,默认当前路径
# res3 = os.path.abspath(r'a/b/c')
# print(res3)
# 判断
# print(os.path.isabs('d:/a'))
# print(os.path.isabs('a'))
# print(os.path.isdir('d:/aaa.data'))# 文件不存在:False
print(os.path.exists('d:/aaa.date'))# 文件不存在:False
print(os.path.isfile('d:a.txt'))# 文件不存在:False
sys模块
命令行:win+r
"""
和python解释器相关的操作
"""
# 获取命令行方式运行的脚本后面的参数
import sys
# print("脚本名:",sys.argv[0]) # 脚本名
# # print("第一个参数:",sys.argv[1]) # 脚本后面第一个参数
# arg1 = int(sys.argv[1])
# arg2 = int(sys.argv[2])
# print(arg1 + arg2)
# 解释器去寻找模块的路径
# sys.path
# 以字典形式返回系统已经加载的模块
# sys.modules
print(sys.modules)
json模块
JavaScript Object Notation:java脚本对象标记语言
已经成为一种简单的数据交换格式
序列化:将内存中的数据,转换成字节串,用以保存在文件或通过网络传输,称为序列化过程
反序列化:从文件中,网络中获取的数据,转换成内存中原来的数据类型,称为反序列化过程
"""
序列化(serialization),拆分过程
反序列化(deserialization),组装过程
"""
# json:将数据转换成字符串,用于存储或网络传输
import json
# s = json.dumps([1,2,3]) # 把指定的对象转换成json格式的字符串
# print(s,type(s)) # [1, 2, 3] <class 'str'>
#
# s1 = json.dumps((1,2,3)) # 元组序列化后,变成列表
# print(s1,type(s1)) # [1, 2, 3] <class 'str'>
#
# res = json.dumps(10)
# print(res,type(res)) # 10 <class 'str'>
#
# res1 = json.dumps({'name':'alex','age':10})
# print(res1,type(res1)) # {"name": "alex", "age": 10} <class 'str'>
# res2 = json.dumps(set('sbc')) # 集合不可序列化
# 将json结果写到文件中
# with open('a',mode = 'at',encoding = 'utf-8') as f:
# json.dump([1,2,3],f)
# 反序列化
# res3 = json.dumps([1,2,3])
# lst = json.loads(res3)
# print(lst,type(lst)) # [1, 2, 3] <class 'list'>
# 元组会变成列表
# a = json.dumps((1,2,3))
# lst1 = json.loads(a)
# print(lst1,type(lst1)) # [1, 2, 3] <class 'list'>
# 从文件中反序列化
# with open('a',encoding='utf-8') as f:
# res = json.load(f)
# print(res,type(res)) # [1, 2, 3] <class 'list'>
# 总结
# json.dumps(obj)
# json.dump(obj,f)
# json.loads(s)
# json.load(f)
# json文件通常是一次性写,一次性读
# 使用另一种方式可以实现多次写,多次读
# 把需要序列化的对象,通过多次序列化的方式,用文件write方法,把多次序列化后的json字符串写到文件中
# with open('json.txt',encoding = 'utf-8',mode='at') as f1:
# f1.write(json.dumps([1,2,3])+'\n')
# f1.write(json.dumps([4,5,6])+'\n')
# 把分次序列化的json字符串,反序列回来
with open('json.txt',encoding = 'utf-8',mode='rt') as f1:
# res = json.loads(f1.readline().strip())
# print(res)
# res2 = json.loads(f1.readline().strip())
# print(res2)
for x in f1:
print(json.loads(x.strip()))
pickle
"""
将python所有的数据类型,转换成字节串,序列化过程
将字节串转换成python中数据类型,反序列化过程
"""
import pickle
# 序列化
# bys = pickle.dumps([1,2,3])
# print(bys,type(bys))# b'\x80\x04\x95\x0b\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03e.' <class 'bytes'>
# bys = pickle.dumps((1,2,3))
# print(bys,type(bys))
#
# # 反序列化
# res = pickle.loads(bys)
# print(res,type(res))# (1, 2, 3) <class 'tuple'>
# 所有数据类型都可以进行序列化
# bys1 = pickle.dumps(set('abc'))
# res1 = pickle.loads(bys1)
# print(res1,type(res1))# {'a', 'b', 'c'} <class 'set'>
# 把序列化内容写入文件中
# with open('c.txt',mode='wb') as f:
# pickle.dump([1,2,3],f)
# 从文件中反序列化pickle数据
# with open('c.txt',mode='rb') as f:
# res = pickle.load(f)
# print(res,type(res))
# 多次pickle数据到同一文件中
# with open('c.txt',mode='ab') as f:
# pickle.dump([1,2,3],f)
# pickle.dump([1, 2, 3], f)
# 多次从文件中反序列化pickle数据
# with open('c.txt',mode='rb') as f:
# for i in range(2):
# res = pickle.load(f)
# print(res)
# pickle最常用的场景:和json一样,一次性写入,一次性读取
json和pickle的比较
json:
1,不是所有的数据类型都可以序列化
2,不能多次对同一个文件序列化
3,json数据可以跨语言
pickle:
1,所有python类型都能序列化,结果是字节串
2,可以多次对同一个文件序列化
3,不能跨语言
hashlib模块
封装一些用于加密的类
md5(),sha1()…
加密的目的:用于判断和验证,而并非解密
特点:
把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总结果,和直接对整体数据加密的结果是一致的。
单向加密,不可逆
原始数据的一点小变化,将导致结果雪崩式差异
"""
md5加密算法
"""
import hashlib
# 获取一个加密对象
# m = hashlib.md5()
# 使用加密对象的update(更新),进行加密
# m.update(b'abc')# 900150983cd24fb0d6963f7d28e17f72 <class 'str'>
# m.update('abc中文'.encode('utf-8'))# 1af98e0571f7a24468a85f91b908d335 <class 'str'>
# 通过hexdigest获取加密结果
# res = m.hexdigest()
# res1 = m.digest()
# print(res,type(res))
# print(res1,type(res1))# b'\x1a\xf9\x8e\x05q\xf7\xa2Dh\xa8_\x91\xb9\x08\xd35' <class 'bytes'>
总结:给一个数据加密的三大步骤
1,获取一个加密对象
2,使用加密对象的update,进行加密,update方法可以调用多次
3,通常通过hexdigest获取加密结果,或者digest()方法
给一个数据加密,
验证:用另一个数据加密的结果和第一次加密的结果对比
如果结果相同,说明原文内容相同,如果不相同,说明原文不同
# 不同加密算法:实际上就是加密结果的长度不同
# s = hashlib.sha224()
# s.update(b'abc')
# print(len(s.hexdigest()))# 56
# print(len(hashlib.md5().hexdigest())) # 32
# 在创建加密对象时,可以指定参数,称为salt
# m = hashlib.md5(b'xyz')
# print(m.hexdigest())
# print(hashlib.md5(b'xyz').hexdigest())
#
# m1 = hashlib.md5()
# m1.update(b'xyz')
# print(m1.hexdigest())
# 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总结果,和直接对整体数据加密的结果是一致的。
# m1 = hashlib.md5()
# m1.update(b'xyz')
# m1.update(b'abc')
# print(m1.hexdigest())
#
# m2 = hashlib.md5()
# m2.update(b'xyzabc')
# print(m2.hexdigest())
# 参数顺序不对则会雪崩!
基本格式
import hashlib
m1 = hashlib.md5()
# m1 = hashlib.sha224()
m1.update(数据)
print(m1.hexdigest())
练习
import hashlib
# 注册,登录程序:
def get_md5(username,password):
m = hashlib.md5()
m.update(username.encode('utf-8'))
m.update(password.encode('utf-8'))
return m.hexdigest()
def register(username,password):
# 加密
res = get_md5(username,password)
# 写入文件
with open('login',mode='a',encoding='utf-8') as f:
f.write(res)
f.write('\n')
def login(username,password):
# 获取当前登录信息的加密结果
res = get_md5(username,password)
# 读文件,和其中的数据进行对比
with open('login',mode='r',encoding='utf-8') as f:
for line in f:
if res == line.strip():
return True
else:
return False
while 1:
op = int(input('1,注册 2,登录 3,退出'))
if op == 1:
username = input('请输入用户名')
password = input('请输入密码')
register(username,password)
elif op == 2:
username = input('请输入用户名')
password = input('请输入密码')
res = login(username,password)
if res:
print('登录成功')
else:
print('登陆失败')
elif op == 3:
break
collections模块
namedtuple():命名元组
# import collections
from collections import namedtuple
# 类名 = namedtuple(用于描述类名的字符串, )
# Rectangle = namedtuple('Rectangle',['length','width'])
# r = Rectangle(10,5)
# # 通过属性访问元组的元素
# print(r.length)
# print(r.width)
# # 通过索引的方式访问元素
# print(r[0])
# print(r[1])
defaultdict():默认值字典
from collections import defaultdict
# 创建字典的方式
# dic = {'name':'alex','age':10}
# dic = dict([('name','alex'),('age',10)])
# dic = {k:v for k,v in [(1,2),(3,4)]}# 列表推导式
# key超出范围会根据自定义补齐
# d = defaultdict(int,name = 'alex',age = 10)
# print(d['name'])
# print(d['age'])
# print(d['ad'])# 0
# print(d['a'])# 0
# print(d)# defaultdict(<class 'int'>, {'name': 'alex', 'age': 10, 'ad': 0, 'a': 0})
# 自定义函数充当第一个参数:
# 要求,不能有参数
# def f():
# return 'hello'
# d = defaultdict(f,name = 'alex',age = 10)
# print(d['as'])# hello
# print(d)# defaultdict(<function f at 0x000001DE126551F0>, {'name': 'alex', 'age': 10, 'as': 'hello'})
Counter():计数器
from collections import Counter
c = Counter('ashdfwueihi')
print(c)# Counter({'h': 2, 'i': 2, 'a': 1, 's': 1, 'd': 1, 'f': 1, 'w': 1, 'u': 1, 'e': 1})
print(c.most_common(3))# [('h', 2), ('i', 2), ('a', 1)]
总结
t’>, {‘name’: ‘alex’, ‘age’: 10, ‘ad’: 0, ‘a’: 0})
自定义函数充当第一个参数:
要求,不能有参数
def f():
return ‘hello’
d = defaultdict(f,name = ‘alex’,age = 10)
print(d[‘as’])# hello
print(d)# defaultdict(<function f at 0x000001DE126551F0>, {‘name’: ‘alex’, ‘age’: 10, ‘as’: ‘hello’})
Counter():计数器
```python
from collections import Counter
c = Counter('ashdfwueihi')
print(c)# Counter({'h': 2, 'i': 2, 'a': 1, 's': 1, 'd': 1, 'f': 1, 'w': 1, 'u': 1, 'e': 1})
print(c.most_common(3))# [('h', 2), ('i', 2), ('a', 1)]
有一些图片加载不了,第一次写不知道怎么弄,多多关照,不明确的地方还请多多指教。