python学习笔记四

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():全部

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值