1.time模块
time.spleep()
让程序沉睡几秒
# 1-1.time.sleep() 可以控制程序执行的效率
import time
print('你好')
time.sleep(2) # 可以暂停执行一段时间
print('你很好')
time.time()
拿到当前时间戳
# 1-2.time.time() 当前时间的时间戳 是一种数字类型的时间 以秒计数
print(time.time())
# time.time() 可以计算时间差
start = time.time()
for i in range(1000):
print(i)
end = time.time()
print(end - start)
格式化时间
import time
print(time.strftime('%Y-%m-%d %H-%M-%S', time.localtime(time.time())))
# 暂停一秒
time.sleep(1)
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
2.datatime
from datetime import datetime # 年月日 时分秒
from datetime import date # 只需要掌握一个用法 年月日 data.today()
datatime
现在时间now()
# 1.想知道现在是什么时间
print(datetime.now())
指定时间
# # 2.想指定一个时间
print(datetime(2023, 3, 21, 14, 38, 20))
时间差total_seconds()
# # 3.时间差
t1 = datetime(2023, 3, 21, 14, 38, 15)
t2 = datetime(2022, 3, 21, 14, 38, 28)
diff = t1 - t2
print(diff) # 364 days, 23:59:47
# total_seconds()转化成秒
print(diff.total_seconds()) # 31535987.0
格式化时间strftime
# 4.格式化一个时间
t = datetime.now()
print(t)
print(t.strftime('%Y年%m月%d日 %H时%M分%S秒'))
# 把时间格式化成一个字符串 str format time
格式化时间strptime
# 5.让用户输入两个时间,计算时间差
s1 = input('请输入时间:格式yyyy-mm-dd hh-mm-ss:')
s2 = input('请输入时间:格式yyyy-mm-dd hh-mm-ss:')
t1 = datetime.strptime(s1, '%Y-%m-%d %H-%M-%S') # str parse time
t2 = datetime.strptime(s2, '%Y-%m-%d %H-%M-%S')
print(t1)
print(t2)
print(t2 - t1)
data
data.today
# 6.data.today
print(date.today())
时间的格式化输出
import datetime
# 获取系统当前日期
t = datetime.date.today()
print(t.strftime('%Y:%m:%d'))
# 创建日期
t1 = datetime.date(1945, 9, 15)
print(t1.strftime('%Y:%m:%d'))
# 日期计算
t2 = t1 - datetime.timedelta(days=-2)
print(t2.strftime('%Y:%m:%d'))
print(datetime.date.strftime(t2, '%Y:%m:%d'))
# 日期替换
t3 = t.replace(year=t.year + 1, month=t.month-1, day=t.day-10)
print(t3.strftime('%Y:%m:%d'))
总结
"""
datatime:
1.datatime.now(): 拿到系统时间
2.strftime():格式化时间,把时间转化成字符串
3.strptime(): 把字符串转化成时间
data:
data.today():今天日期
"""
3.random
常用方法
# 随机
"""
random:
1.random.random(): (0,1)之间的一个随机小数
2.random.uniform(5,9): 5到9之间的随机小数
3.random.ranint(3,8): 随机整数,且能取到边界
4.random.choice(lst): 从列表里面随机选择一个 random.choices(lst, k=2) 随机选择2个 这两个有可能相同
5.random.sample(lst, k=2): 从列表里面随机拿出两个 这两个不同
"""
练习1
print(random.random())
lst = ['张无忌', '张三丰', '张翠山', '谢逊', '殷素素', '殷天正', '殷野王']
print(random.choice(lst))
print(random.choices(lst, k=2))
print(random.sample(lst, k=2))
练习2
# 练习:验证码:4位验证码 可以是数字 可以是大写字母 可以是小写字母
def rand_num():
return str(random.randint(0, 9))
def rand_upper():
return chr(random.randint(65, 90))
# 大写字母ascii码范围
def rand_lowwer():
return chr(random.randint(97, 122))
# 小写字母ascii码范围
def rand_verify_code(n=4): # 默认值参数 n=4
lst = []
for i in range(n):
which = random.randint(1, 3)
if which == 1:
s = rand_num()
elif which == 2:
s = rand_upper()
elif which == 3:
s = rand_lowwer()
lst.append(s)
return ''.join(lst)
# 把列表转成字符串
print(rand_verify_code())
chr()
把ascii码转化成对应的符号,结果是字符串
t = chr(98)
print(t)
print(type(t))
4.pickle
把python对象转换成字节
序列化:把对象转化成二进制字节
反序列化:把二进制字节转化回对象
dumps
把对象(数据)转化成字节
lst = ['赵本山', '范围', '六老哥', '马大帅']
bs = pickle.dumps(lst) # 把对象转换成字节
print(bs)
loads
把字节转化回对象(数据)
bs = b'\x80\x04\x952\x00\x00\x00\x00\x00\x00\x00]\x94(\x8c\t\xe8\xb5\xb5\xe6\x9c\xac\xe5\xb1\xb1\x94\x8c\x06\xe8\x8c\x83\xe5\x9b\xb4\x94\x8c\t\xe5\x85\xad\xe8\x80\x81\xe5\x93\xa5\x94\x8c\t\xe9\xa9\xac\xe5\xa4\xa7\xe5\xb8\x85\x94e.'
lst = pickle.loads(bs) # 把字节转化成对象
print(lst)
dump
把对象序列化成字节之后写入文件
lst = ['赵本山', '范围', '六老哥', '马大帅']
pickle.dump(lst, open('pickle.txt', 'wb')) # 这个文件是给计算机看的
load
把文件中的字节反序列化成对象
lst1 = pickle.load(open('pickle.txt', 'rb'))
print(lst1)
5.json
1.json 是一种数据类型
2.来自前端
3.dumps dump 在处理汉字时 必须加上ensure_ascii=Flase,否则汉字会以字节的形式出现
4.loads load
dumps
把python中的字典或列表转化成json字符串
1.处理dic里面的数字和英文
dic = {'id': 1, 'name': 'admin', 'usertype': 0}
s = json.dumps(dic)
print(s, type(s))
2.处理dic里面的汉字
json 会自动将汉字转化成ascii码
dic = {'id': 1, 'name': '马大帅', 'usertype': 0}
s = json.dumps(dic)
print(s, type(s)) # {"id": 1, "name": "\u9a6c\u5927\u5e05", "usertype": 0} <class 'str'>
print(ascii('马大帅')) # '\u9a6c\u5927\u5e05'
3.汉字不使用ascii码
处理dic里面的汉字 在转化时要注明 不使用ascii码
dic = {'id': 1, 'name': '马大帅', 'usertype': 0}
s = json.dumps(dic, ensure_ascii=False) # 确定不适用ascii码 ensure_ascii=False
print(s, type(s)) # {"id": 1, "name": "马大帅", "usertype": 0} <class 'str'>
4.列表一样可以转化
lst = ['张无忌', '张翠山', '马大帅', '范伟', True]
j = json.dumps(lst)
print(j, type(j)) # ["\u5f20\u65e0\u5fcc", "\u5f20\u7fe0\u5c71", "\u9a6c\u5927\u5e05", "\u8303\u4f1f", true] <class 'str'>
j = json.dumps(lst, ensure_ascii=False)
print(j, type(j)) # ["张无忌", "张翠山", "马大帅", "范伟", true] <class 'str'>
loads
前端返回的json字符串,想办法变成python中的字典.
# 2-1 把字符串转化成字典
s = '{"id": 1, "name": "马大帅", "usertype": 0}'
d = json.loads(s)
print(d, type(d)) # {'id': 1, 'name': '马大帅', 'usertype': 0} <class 'dict'>
dump
把字典写入到文件中
wf = {
'name': '章子怡',
'age': '38',
'children': {
'name': '汪小峰',
'age': '18'
},
}
json.dump(wf, open('wf.txt', 'w', encoding='utf-8'))
# {"name": "\u7ae0\u5b50\u6021", "age": "38", "children": {"name": "\u6c6a\u5c0f\u5cf0", "age": "18"}}
json.dump(wf, open('wf1.txt', 'w', encoding='utf-8'), ensure_ascii=False)
# {"name": "章子怡", "age": "38", "children": {"name": "汪小峰", "age": "18"}}
load
从文件中读字典
d1 = json.load(open('wf.txt', 'r', encoding='utf-8')) # 在读取的时候 字典中的ascii码会转化成汉字
print(d1, type(d1))
d2 = json.load(open('wf1.txt', 'r', encoding='utf-8'))
print(d2, type(d2))
总结
1.dumps: 把对象转json 即把字典等数据类型转成字符串
2.loads: 把json转对象 即把字符串转成python对象
3.dumps dump 在处理汉字时 必须加上ensure_ascii=Flase,否则汉字会以字节的形式出现
6.hashlib
是一种关于数据加密的模块
md5
md5是一种不可逆的加密算法,安全可靠 在python中hashlib模块就能搞定MD5加密
字符串加密
# 创建MD5对象
obj = hashlib.md5()
# 把要加密的信息传递给obj,obj只能接受字节,所以需要将传递的信息转成字节
obj.update('666666'.encode('utf-8'))
# 从obj中拿到密文
mi = obj.hexdigest()
print(mi, type(mi)) # f379eaf3c831b04de153469d1bec345e <class 'str'>
加盐
正常的默认加密过程是容易撞库的
撞库:即密文曾经被生成过 存储到一个库里,再拿密文去查询,就能得到明文的值
解决撞库:加盐 盐必须是字节
obj = hashlib.md5(b'asdasdsad') # 这就是加盐
obj.update('666666'.encode('utf-8'))
mi = obj.hexdigest()
print(mi) # 2c66b38bb23f395b28519c88969ab6ed
应用
用户注册
# 用户注册
def func(salt, s):
obj = hashlib.md5(salt)
obj.update(s.encode('utf-8')) # 为对象传递信息 必须用字节
return obj.hexdigest()
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
mi_password = func(username.encode('utf-8'), password) # 把username当成盐,盐必须是字节 所以要.encode('utf-8')
mi1_password = func(password.encode('utf-8'), password) # 把password当成盐
print(mi1_password)
f = open('denglu.txt', 'w', encoding='utf-8')
f.write(username)
f.write('\n')
f.write(mi1_password)
f.close()
用户登录
def func(salt, s):
obj = hashlib.md5(salt)
obj.update(s.encode('utf-8')) # 为对象传递信息 必须用字节
return obj.hexdigest()
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
password = func(password.encode('utf-8'), password)
f = open('denglu.txt', 'r', encoding='utf-8')
uname = f.readline().strip()
upword = f.readline().strip()
# 需要把用户输入的明文加密后再进行判断
if username == uname and password == upword:
print('登录成功')
else:
print('登录失败')
文件加密
# 2.MD5对文件进行加密 例如把wf1.txt进行MD5加密
obj = hashlib.md5(b'sadfgfdd') # 先加盐
with open('wf1.txt', 'rb') as f:
for line in f:
obj.update(line) # 此时的line已经是字节的形式
# 得到加密结果
print(obj.hexdigest()) # bea3f03f412bf4145baba6ad5a8a1a57
用途
判断文件的一致性
一致性:两个相同文件MD5的值是一定的
例如:网盘传递信息,先计算MD5的值
如果有这个值,就直接复制过去
7.shutil
封装文件或文件夹的相关操作 比如:复制 粘贴 移动
文件操作
# 1.把dir1/a.txt移动到dir2里面
shutil.move('dir1/a.txt', 'dir2')
# 2-1复制两个文件句柄 把dir2/a.txt复制到dir1/b.txt
f1 = open('dir2/a.txt', mode='rb')
f2 = open('dir1/b.txt', mode='wb')
shutil.copyfileobj(f1, f2) # 把f1复制到f2
# 2-2 执行两个文件路径进行文件的复制
# 这种操作只能复制文件内容,但是权限修改时间等都不会被复制
shutil.copyfile('dir1/b.txt', 'dir1/c.txt')
# 2-3 不经复制文件内容 还要复制文件权限
shutil.copy('dir1/b.txt', 'dir1/e.txt')
# 2-4 复制文件内容 权限 修改时间
shutil.copy2('4-1模块.py', 'dir1/f.py')
# 2-5 修改时间 和权限的复制 但是不修改内容
shutil.copystat('4-1模块.py', 'dir2/a.txt')
# 2-6 只拷贝权限
shutil.copymode('4-1模块.py', 'dir1/b.txt')
文件夹操作
# 3-1 复制文件夹
shutil.copytree('dir1', 'dir3') # 没有dir3 会自动创造dir3
# 3-2 删除文件夹
shutil.rmtree('dir3')
8.logging
用来记录日志的模块
"""
1.导入logging模块
2.简单配置一下logging
3.出现异常的时候(except),向日志里些信息
"""
"""
filename:文件名
format: 数据的格式化输出,最终再日志文件中的样子
时间--名称--级别--模块:错误信息
datafmt: 时间的格式
level: 错误的级别权重,当错误的级别权重大于level时才会写入文件
"""
logging.basicConfig(filename='x1.txt',
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=0) # 记录文件日志的最低等级 0表示记录一切错误信息
# logging 日志记录
logging.critical('今天系统炸了') # 50 最高级别的日志信息
logging.error('程序出现了BUG') # 40
logging.warning('这只是一个警告') # 30
logging.info('只是一个普通信息') # 20
logging.debug('默认最低等级的消息') # 10
# logging.ERROR
9.异常处理
try execept
try:
print(1/0)
open('a.txt', 'r', encoding='utf-8').read()
except ZeroDivisionError: # 除数为0
print('除数为0')
except FileNotFoundError: # 找不到文件
print('文件没找到')
except Exception as e: # 可接受所有的文件类型
print(e)
finally:
print('收尾') # 不管是否报错 finally都会执行
raise
程序主动抛出错误
# 计算两个整数的和
def func(a, b):
if type(a) == int and type(b) == int:
return a + b
else:
# 抛出异常
raise Exception('你给我的不是int数据类型,func函数无法计算')
sum_ = func(1, 2)
print(sum_)
总结
1.处理异常 try execpt
2.抛出异常 raise
10.traceback
追溯错误信息
优点:不会阻断程序的继续运行
traceback.format_exc的使用
try:
print(1/0)
except:
print('程序出错了')
print(traceback.format_exc())
print('666666')
# 优点:不会阻断程序的继续运行
logging和traceback搭配使用
logging.basicConfig(filename='x3.txt',
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=0) # 记录文件日志的最低等级 0表示记录一切错误信息
try:
print(1/0)
except:
print('程序出错了')
logging.error(traceback.format_exc()) # 将错误写入日志
11.zipfile
创建压缩包
f = zipfile.ZipFile('zip_dir/abc.zip', 'w')
f.write('x1.txt')
f.write('x2.txt')
f.close()
解压缩
f = zipfile.ZipFile('zip_dir/abc.zip', 'r')
全部解压缩
f.extractall('zip_dir/abcd') # 把解压缩后压缩包里的文件放到zip_dir/abcd这个目录里面
每个文件单独解压缩
print(f.namelist())
for name in f.namelist():
f.extract(name, 'zip_dir/abc')
只解压一个文件
f.extract(f.namelist()[0], 'zip_dir/abc1')
12.re
查找
findall
# 1-1.findall:从一串字符中提取到所有数字
res = re.findall('\d+', '我今年18岁了,我喜欢5个明星.')
res1 = re.findall('我今年(\d+)岁了,我喜欢(\d+)个明星.', '我今年18岁了,我喜欢5个明星.')
res2 = re.findall('我今年\d+岁了,我喜欢\d+个明星.', '我今年18岁了,我喜欢5个明星.')
print(res, type(res))
print(res1, type(res1))
print(res2, type(res2))
['18', '5'] <class 'list'>
[('18', '5')] <class 'list'>
['我今年18岁了,我喜欢5个明星.'] <class 'list'>
search
# 1-2.search:判断一句话中是否有数字
# search特点:匹配字符串 匹配到一个结果就返回 不会匹配出多个结果
res = re.search('\d+', '我今年18岁了,我喜欢5个明星.')
print(res, type(res)) # <re.Match object; span=(3, 5), match='18'> <class 're.Match'>
print(res.group(), type(res.group())) # 18 <class 'str'>
finditer
# 1-3.finditer:所有的数字都会进行匹配,返回的时迭代器
res = re.finditer(r'\d+', '我今年18岁了,我喜欢5个明星.')
print(res) # <callable_iterator object at 0x000001FC466B9F90>
for item in res:
print(item.group())
match
# 1-4.match: 从头开始匹配.
res = re.match('\d+', '我今年18岁了,我喜欢5个明星.')
print(res, type(res)) # None <class 'NoneType'>
res = re.match('\d+', '18岁了,我喜欢5个明星.')
print(res, type(res)) # <re.Match object; span=(0, 2), match='18'> <class 're.Match'>
print(res.group(), type(res.group())) # 18 <class 'str'>
其他操作
split
# 2-1.split:切割
lst = re.split('\d+', '我今年18岁了,我喜欢5个明星.') # 根据数字切割,返回的是一个列表
print(lst, type(lst))
lst = re.split('[我了]', '我今年18岁了,我喜欢5个明星.') # 根据‘我‘,’了‘切割,返回的是一个列表
print(lst, type(lst))
sub
# 2-2sub:做替换
res = re.sub(r'\d+', '_sb_', '我今年18岁了,我喜欢5个明星.')
print(res, type(res)) # 我今年_sb_岁了,我喜欢_sb_个明星. <class 'str'>
subn
# 2-3. subn:返回的是一个元组,可以显示替换的次数
res = re.subn(r'\d+', '_sb_', '我今年18岁了,我喜欢5个明星.')
print(res, type(res)) # ('我今年_sb_岁了,我喜欢_sb_个明星.', 2) <class 'tuple'>
compile
# 2-4.re.compile():预设置
obj = re.compile(r'\d+') # 先加载这个正则,后面可以用这个正则去匹配内容
lst = obj.findall('我今天吃了2碗大米,3个馒头,再加4个鸡蛋.')
print(lst) # ['2', '3', '4']
爬虫
r’*****’
# 字符串中经常出现\n,为了避免出现问题,可以在字符前写上r,把字符串内容全部当成普通字符来处理
print('我叫周杰伦\n我i今年18岁了')
print(r'我叫周杰伦\n我i今年18岁了')
# 我叫周杰伦
# 我i今年18岁了
# 我叫周杰伦\n我i今年18岁了
获取
1.()里的内容是我们最终想要的内容;
2.(?P正则) 把正则匹配到的内容直接放到name组里,后面取数据的时候 直接group(‘name’)
obj = re.compile(r'昨天我吃了(?P<mian>\d+)个馒头,喝了(?P<tang>\d+)碗汤')
it = obj.finditer('前天,我吃了3个馒头,喝了2碗汤,昨天我吃了5个馒头,喝了4碗汤,今天我吃了1个馒头,喝了6碗汤')
for item in it:
print(item.group('mian')) # 5
print(item.group('tang')) # 4
print(item.groupdict()) # {'mian': '5', 'tang': '4'}
总结
1.查找:
1.findall: 匹配所有 返回列表
2.finditer: 匹配所有 返回迭代器
3.search:匹配带一个结果就返回
4.match:从头匹配 得到一个结果就返回
2.拿数据:
1.group:拿数据
2.group(组名)
3.():
1.():从正则匹配的结果中拿到指定数据
2.(?P正则):把匹配的结果分组
4.预编译:
re.compile:提前把需要匹配的正则编译好 后面可以直接用
5.findall查找:
有():只要()里面的
没():匹配信息全部都要
其他查找:
有():
group():全部
group(1):匹配的第一个括号里面的信息
group(2):匹配的第二个括号里面的信息
没():
group():全部