常用的内置模块
时间模块
这个模块我们就比较熟悉了,之前学的时候调用过内部的几个功能
三种时间表现形式
1.时间戳(timestamp)
返回秒数。通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
2.结构化时间(struct_time)
主要是给计算机看的,人看不适应,但是根据中间的单词意思也可以看懂
这里需要注意,因为外国的日期和星期跟我们不太一样,我们需要根据具体情况修改。
3.格式化时间(Format String)
主要是给人看的,通过一定的符号表示对应的年月日时分秒
代码演示:
#导入时间模块
import time
#时间戳
print(time.time())
# 结果:1666168973.8717413
#时间字符串
print(time.strftime("%Y-%m-%d %X"))
# 结果:2022-10-19 16:42:53
print(time.strftime("%Y-%m-%d %H-%M-%S"))
# 前面三个表示日期的%字符可以用%+小写的x表示,后面三个表示时间的%字符可以用大写的X表示
# 结果:2022-10-19 16-42-53
#时间元组:localtime将一个时间戳转换为当前时区的struct_time
print(time.localtime())
# 结果:time.struct_time(tm_year=2022, tm_mon=10, tm_mday=19, tm_hour=16, tm_min=42, tm_sec=53, tm_wday=2, tm_yday=292, tm_isdst=0)
拓展1:
格式化时间中,各个符号代表的意思:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
拓展2:
struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
索引(Index) | 属性(Attribute) | 值(Values) |
---|---|---|
0 | tm_year(年) | 比如2011 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 60 |
6 | tm_wday(weekday) | 0 - 6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
几种时间格式的转换
import time
#时间戳-->结构化时间
# time.gmtime(时间戳) # 根据UTC时间进行转换,与英国伦敦当地时间一致
# time.localtime(时间戳) # 根据当地时间进行转换。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间
print(time.gmtime(1500000000))
# 结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
print(time.localtime(1500000000))
# 结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
#结构化时间-->时间戳
#time.mktime(结构化时间)
time_tuple = time.localtime(1500000000)
print(time.mktime(time_tuple))
# 结果:1500000000.0
import time
#结构化时间-->字符串时间
#time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间
print(time.strftime("%Y-%m-%d %X"))
# 结果:'2017-07-24 14:55:36'
print(time.strftime("%Y-%m-%d", time.localtime(1500000000)))
# 结果:'2017-07-14'
#字符串时间-->结构化时间
#time.strptime(时间字符串,字符串对应格式)
print(time.strptime("2017-03-16", "%Y-%m-%d"))
# 结果:time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
print(time.strptime("07/24/2017", "%m/%d/%Y"))
# 结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
import time
#结构化时间 --> %a %b %d %H:%M:%S %Y串
#time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串
print(time.asctime(time.localtime(1500000000)))
# 结果'Fri Jul 14 10:40:00 2017'
print(time.asctime())
# 结果'Mon Jul 24 15:18:33 2017'
#时间戳 --> %a %b %d %H:%M:%S %Y串
#time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串
print(time.ctime())
# 结果'Mon Jul 24 15:19:07 2017'
print(time.ctime(1500000000))
# 结果'Fri Jul 14 10:40:00 2017'
datetime模块
1.datetime.now() # 获取当前datetime
datetime.utcnow() # 获取当前格林威治时间
from datetime import datetime
#获取当前本地时间
a=datetime.now()
print('当前日期:',a)
#获取当前世界时间
b=datetime.utcnow()
print('世界时间:',b)
2.datetime(2017, 5, 23, 12, 20) # 用指定日期时间创建datetime
from datetime import datetime
#用指定日期创建
c=datetime(2017, 5, 23, 12, 20)
print('指定日期:',c)
3.将以下字符串转换成datetime类型:
'2017/9/30'
'2017年9月30日星期六'
'2017年9月30日星期六8时42分24秒'
'9/30/2017'
'9/30/2017 8:42:50 '
from datetime import datetime
d=datetime.strptime('2017/9/30','%Y/%m/%d')
print(d)
e=datetime.strptime('2017年9月30日星期六','%Y年%m月%d日星期六')
print(e)
f=datetime.strptime('2017年9月30日星期六8时42分24秒','%Y年%m月%d日星期六%H时%M分%S秒')
print(f)
g=datetime.strptime('9/30/2017','%m/%d/%Y')
print(g)
h=datetime.strptime('9/30/2017 8:42:50 ','%m/%d/%Y %H:%M:%S ')
print(h)
4.将以下datetime类型转换成字符串:
2017年9月28日星期4,10时3分43秒
Saturday, September 30, 2017
9/30/2017 9:22:17 AM
September 30, 2017
from datetime import datetime
i=datetime(2017,9,28,10,3,43)
print(i.strftime('%Y年%m月%d日%A,%H时%M分%S秒'))
j=datetime(2017,9,30,10,3,43)
print(j.strftime('%A,%B %d,%Y'))
k=datetime(2017,9,30,9,22,17)
print(k.strftime('%m/%d/%Y %I:%M:%S%p'))
l=datetime(2017,9,30)
print(l.strftime('%B %d,%Y'))
5.用系统时间输出以下字符串:
今天是2017年9月30日
今天是这周的第?天
今天是今年的第?天
今周是今年的第?周
今天是当月的第?天
from datetime import datetime
#获取当前系统时间
m=datetime.now()
print(m.strftime('今天是%Y年%m月%d日'))
print(m.strftime('今天是这周的第%w天'))
print(m.strftime('今天是今年的第%j天'))
print(m.strftime('今周是今年的第%W周'))
print(m.strftime('今天是当月的第%d天'))
随机数模块:random
功能简介:
import random
# 随机小数
print(random.random())
# 大于0且小于1之间的小数
# 0.7664338663654585
print(random.uniform(1, 3))
# 大于1小于3的小数
# 1.6270147180533838#恒富:发红包
# 随机整数
print(random.randint(1, 5))
print(random.randrange(1, 10, 2))
# 随机选择一个返回
print(random.choice([1, '23', [4, 5]]))
print(random.choices([1, '23', [4, 5]]))
# choices返回的不是字符了,返回的是保留原来数据类型的数据值
# 随机选择多个返回,返回的个数为函数的第二个参数
print(random.sample([1, '23', [4, 5]], 2))
# [[4, 5], '23']
# 打乱列表顺序
item = [1, 3, 5, 7, 9]
random.shuffle(item) # 打乱次序
print(item)
# [5, 1, 3, 7, 9]
random.shuffle(item)
print(item)
# [5, 9, 7, 1, 3]
产生图片验证码(搜狗面试题):
每一位都可以是大写字母 小写字母 数字 n位
import random
def suijishu(n):
res = ''
for i in range(n):
wd_d = chr(random.randint(65, 90))
wd = chr(random.randint(97, 122))
num = str(random.randint(0, 9))
choice = random.choice([wd, wd_d, num])
res = res + choice
print(res)
suijishu(5)
os模块(重要)
OS模块主要用于代码与操作系统的交互
1、mkdir/makedirs
创建目录(文件夹)
import os
# 1.创建目录(文件夹)
os.mkdir(r'd1')
# 相对路径 在执行文件所在的路径下创建目录 可以创建单级目录
os.mkdir(r'd2\d22\d222')
# 不可以创建多级目录
os.makedirs(r'd2\d22\d222')
# 可以创建多级目录
os.makedirs(r'd3')
# 也可以创建单级目录
2、rmdir/removedirs
删除目录(文件夹),内部有文件的不能删除
os.rmdir(r'd1')
# 可以删除单级目录
os.rmdir(r'd2\d22\d222') # 不可以一次性删除多级目录
os.removedirs(r'd2\d22') # 可以删除多级目录
os.removedirs(r'd2\d22\d222\d2222') # 只能删除空的多级目录
os.rmdir(r'd3') # 只能删空的单级目录
3、listdir
列举指定路径下内容名称
print(os.listdir())
print(os.listdir(r'D:\\'))
4、rename/remove
重命名/删除文件
os.rename(r'a.txt', r'aaa.txt')
# 把a.txt命名成aaa.txt
os.remove(r'aaa.txt')
5、getcwd/chdir
获取/切换当前工作目录
print(os.getcwd())
# D:\pythonProject03\day19
os.chdir('..')
# 切换到上一级目录
print(os.getcwd())
# D:\pythonProject03
os.mkdir(r'hei')
6、abspath/dirname
动态获取项目根路径(重要)
print(os.path.abspath(__file__))
# 获取执行文件的绝对路径(具体到文件名称) D:/pythonProject03/day19/01 os模块.py
print(os.path.dirname(__file__))
# 获取执行文件所在的目录路径(具体到文件的所在文件夹)D:/pythonProject03/day19
7、exists/isfile/isdir
判断路径是否存在(文件、目录)
print(os.path.exists(r'01 os模块.py')) # 判断文件路径是否存在 True
print(os.path.exists(r'D:\pythonProject03\day19'))
# 判断目录是否存在 True
print(os.path.isfile(r'01 os模块.py')) # 判断路径是否是文件 True
print(os.path.isfile(r'D:\pythonProject03\day19'))
# 判断路径是否是文件 False
print(os.path.isdir(r'01 os模块.py')) # False
print(os.path.isdir(r'D:\pythonProject03\day19'))
# True
8、join
路径拼接(重要)
s1 = r'D:\pythonProject03\day19'
s2 = r'01 os模块.py'
print(f'{s1}\{s2}')
"""
涉及到路径拼接一定不要自己做 因为不同的操作系统路径分隔符不一样
"""
print(os.path.join(s1, s2))
9、getsize
获取文件大小(字节)
print(os.path.getsize(r'a.txt'))
10、其他功能
# 获取文件/目录信息
print(os.stat(r'modeos.py'))
# 结果:os.stat_result(st_mode=33206, st_ino=5066549580814332, st_dev=504610996, st_nlink=1, st_uid=0, st_gid=0,
# st_size=2975, st_atime=1666252445, st_mtime=1666252445, st_ctime=1666250317)
# 运行shell命令,直接显示
os.system("bash command")
# 运行shell命令,获取执行结果
os.popen('bash command').read()
# 返回path最后的文件名。如果path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
print(os.path.basename(r'D:/pythonproject/10.20/')) # 返回空值
print(os.path.basename(r'D:/pythonproject/10.20/modeos.py'))
# 结果:modeos.py
# 如果path是绝对路径,返回True
print(os.path.isabs(r'modeos.py'))
# 结果:False
print(os.path.isabs(r'D:/pythonproject/10.20/modeos.py'))
# 结果:True
# 返回path所指向的文件或者目录的最后访问时间
print(os.path.getatime(r'D:/pythonproject/10.20'))
# 结果:1666252253.9921
# 返回path所指向的文件或者目录的最后修改时间
print(os.path.getmtime(r'D:/pythonproject/10.20/modeos.py'))
# 结果:1666252253.9710982
sys模块
sys模块用于跟python解释器进行交互,比如之前设置系统的环境变量位置
1、arge
实现从程序外部向程序传递参数,当我们在pycharm运行文件的时候并不能实现外部传参的功能
res = sys.argv
if len(res) != 3:
print('执行命令缺少了用户名或密码')
else:
username = res[1]
password = res[2]
if username == 'jason' and password == '123':
print('jason您好 文件正常执行')
else:
print('您不是jason无权执行该文件')
这段代码的作用就是判断有没有传参数进来,没有,传了参数就进行判断信息是否正确
2、path
获取执行文件的环境变量
import sys
# 获取执行文件的sys.path(环境变量,前两个是一样的,因为pycharm帮我们加了一次,然后我们运行的时候当前路径也会加进去)
print(sys.path)
# 结果:['D:\\pythonproject\\10.20', 'D:\\pythonproject\\10.20', 'D:\\PyCharm 2021.1.3\\plugins\\python\\helpers\\pycharm_display',
# 'D:\\python3.8\\python38.zip', 'D:\\python3.8\\DLLs', 'D:\\python3.8\\lib', 'D:\\python3.8',
# 'D:\\python3.8\\lib\\site-packages', 'D:\\PyCharm 2021.1.3\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
3、getrecursionlimit
获取python解释器默认最大递归深度
# 获取python解释器默认最大递归深度
print(sys.getrecursionlimit()) # 默认为1000
4、setrecursionlimit
修改python解释器默认最大递归深度
# 修改python解释器默认最大递归深度
sys.setrecursionlimit(2000)
5、version
返回当前的解释器版本
# 返回当前的解释器版本
print(sys.version)
# 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)]
6、platform
返回平台信息
# 返回平台信息
print(sys.platform)
# 平台信息 基本都是win32(了解即可)
7、exit
返回程序中间的退出信息,arg=0为正常退出,其他为异常退出
json模块
json模块用于不同语言之间的数据传输。json模块也称为序列化模块,序列化可以打破语言限制实现不同编程语言之间数据交互。
序列化:数据类型>>>json格式字符串
特征:文件中引号是双引号
json模块有四个方法:dump、load、dumps、loads
json相关操作
针对数据
json.dumps()
json.loads()
dumps可以直接将数据变成json格式,load可以用于将json格式数据变成python格式
针对文件
json.dump()
json.load()
使用dump可以将数据序列号(变成json格式)然后写入文件,load可以将json文件中的序列化数据转化成python格式。
在Python中把其他数据类型转为json需要使用json模块
import json # 内置的
import json
# 1. 把字典类型转为json格式的数据
"""
json模块中与四个方法
json.dumps---->序列化用的 json.loads------》反序列化
json.dump------》序列化,它可以直接写入文件 json.load-----------》它能够读取文件,然后自动反序列化
"""
d = {"username":"kevin", 'age':18} # {"username": "kevin", "age": 18}
# 序列化
print(type(d)) # dict
print(json.dumps(d), type(json.dumps(d))) # <class 'str'> {"username": "kevin", "age": 18}
## json格式的数据特点:字典里面的都变成了双引号
"""通过网络传输的数据一定是二进制"""
# 反序列化:java给你发送了数据------------》
res = b'{"username": "kevin", "age": 18}'
# 把二进制数据转为Python中得字典
print(res.decode('utf-8'), type(res.decode('utf-8'))) # {"username": "kevin", "age": 18}
s1 = res.decode('utf-8') # 把字符串格式的json转为抛Python中得字典
print(json.loads(s1), type(json.loads(s1)))
d1 = json.loads(s1)
print(d1['username'])
"""字节类型------》字符串-----------》字典"""
json模式就是把数据转换为json模式下的字符串
json习题
1. 把字典格式的数据写入到文件中
d = {'username':'jerry', 'age':18}
写入文件必须是二进制或者字符串
with open('a.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(d))
2. 从文件中读取数据并且要是字典格式
with open('a.txt', 'r', encoding='utf-8') as f1:
res=eval(f1.read()) # {'username': 'jerry', 'age': 18}
print(res, type(res))
3. 非常方便的写入文件
with open('a.txt', 'w', encoding='utf-8') as f:
# 1. 先把数据序列化,2. 把数据write进去
json.dump(d, f)
4. 从文件读取json格式的字符串
with open('a.txt', 'r', encoding='utf-8') as f1:
1. 先反序列化,然后读出来
res=json.load(f1) # {'username': 'jerry', 'age': 18}
print(res, type(res))
"""补充扩展"""
d = {'username':'jerry你好啊', 'age':18}
"""有时候可以查看源码来学习一些新东西,以后遇到函数不知道怎么用,就要追代码. """
print(json.dumps(d,ensure_ascii=False)) # {"username": "jerry\u4f60\u597d\u554a", "age": 18}
### 难道说Python中得所有数据类型都可以序列化成json? 不是
json.JSONEncoder
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+
pickle模块
"""pickle的使用方式跟json一模一样,json中有四个方法,pickle也是这四个方法"""
能够被序列化的数据类型不一样,json能够序列化的数据类型是有限的
有:dict list, tuple str int, float True False None
pickle能够序列化的类型:所有数据类型
"""它不好的地方在于,被pickle处理之后的数据只能够在Python中使用"""
# 另外,pickle序列化之后的结果是二进制的
# d = {"a":1, 'b':2}
l = [1 ,2 ,3 ,4]
import pickle
# print(pickle.dumps(d)) # b'\x80\x04\x95\x11\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x01a\x94K\x01\x8c\x01b\x94K\x02u.'
print(pickle.dumps(l)) # b'\x80\x04\x95\r\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04e.'
res = pickle.dumps(l)
print(pickle.loads(res))
# with open('a.txt', 'wb') as f:
# pickle.dump(l, f)
with open('a.txt', 'rb') as f:
print(pickle.load(f))
hashlib模块
hashlib模块是用于数据加密的,模块中有很多种加密算法,比如md5、base64、hmac、sha1等sha系列的加密算法。
1、何为加密
将明文数据处理成密文数据 让人无法看懂(无法逆转),但是可以通过已经加密过的结果进行穷举,来推测明文。
2、为什么加密
为了保证数据的安全
3、如何判断数据是否以加密
我们可以观看数据的构成,如果是用无序的数字、字母、符号来组成的,基本上都是加密数据
4、密文的长短有什么意义
密文越长表示两种情况,第一种就是明文很长,第二种就是加密的算法很复杂,这里我们需要注意算法并不是越复杂越好,应该根据实际情况选择使用,有些时候反而使用简单的算法就足够了。
5.加密算法基本操作
import hashlib
# 1.选择加密算法
md5 = hashlib.md5()
# 2.传入明文数据
md5.update(b'hello')
# 3.获取加密密文
res = md5.hexdigest()
print(res) # 5d41402abc4b2a76b9719d911017c592
6、加密补充说明
1.加密算法不变 内容如果相同 那么结果肯定相同
# md5.update(b'hello~world~python~666') # 一次性传可以
md5.update(b'hello') # 分多次传也可以
md5.update(b'~world') # 分多次传也可以
md5.update(b'~python~666') # 分多次传也可以
2.加密之后的结果是无法反解密的
只能从明文到密文正向推导 无法从密文到明文反向推导
常见的解密过程其实是提前猜测了很多种结果
123 密文
321 密文
222 密文
3.加盐处理
在明文里面添加一些额外的干扰项
# 1.选择加密算法
md5 = hashlib.md5()
# 2.传入明文数据
md5.update('公司设置的干扰项'.encode('utf8'))
md5.update(b'hello python') # 一次性传可以
# 3.获取加密密文
res = md5.hexdigest()
print(res) # e53024684c9be1dd3f6114ecc8bbdddc
4.动态加盐
干扰项是随机变化的
eg:当前时间、用户名部分...
5.加密实战操作
1.用户密码加密
2.文件安全性校验
3.文件内容一致性校验
4.大文件内容加密
截取部分内容加密即可
比如一种情况就是,在一个大文件的每隔四分之一处取一千个字节进行加密,如果两个文件的密文一样说明,这里就是一样的两个文件
7.加密实战
#### 加盐:加密的时候在多一个干扰项
## 注册功能
# username = input('username:>>>').strip()
# password = input('password:>>>').strip()
#
# s_passowrd = password + 'qaz'
# m = hashlib.md5()
# m.update(s_passowrd.encode('utf-8'))
# new_pwd = m.hexdigest()[0:16]
# data = '%s|%s' % (username, new_pwd)
#
# with open('userinfo.txt', 'w', encoding='utf-8') as f:
# f.write(data)
### 登录
# username = input('username:>>>').strip()
# password = input('password:>>>').strip()
#
# s_passowrd = password + 'qaz'
# m = hashlib.md5()
# m.update(s_passowrd.encode('utf-8'))
# new_pwd = m.hexdigest()[0:16]
#
# with open('userinfo.txt', 'r', encoding='utf-8') as f:
# real_username, real_password = f.read().split('|')
#
# if username == real_username and real_password == new_pwd:
# print('登录成功')
# else:
# print('用户名或者密码错误')
import random
def get_code(n):
code = ''
for i in range(n):
random_int = str(random.randint(0, 9))
random_upper = chr(random.randint(65, 90))
random_lower = chr(random.randint(97, 122))
temp = random.choice([random_int, random_upper, random_lower])
code += temp
return code
## 玩法三:终极玩法
# username = input('username:>>>').strip()
# password = input('password:>>>').strip()
#
# random_str = get_code(4) # qazw
# s_passowrd = password + random_str
# m = hashlib.md5()
# m.update(s_passowrd.encode('utf-8'))
# new_pwd = m.hexdigest()[0:16]
# data = '%s|%s|%s\n' % (username, new_pwd, random_str)
#
# with open('userinfo.txt', 'a', encoding='utf-8') as f:
# f.write(data)
username = input('username:>>>').strip()
password = input('password:>>>').strip()
with open('userinfo.txt', 'r', encoding='utf-8') as f:
real_username, real_password, random_str = f.read().split('|')
s_passowrd = password + random_str
m = hashlib.md5()
m.update(s_passowrd.encode('utf-8'))
new_pwd = m.hexdigest()[0:16]
if username == real_username and new_pwd == real_password:
print('密码正确')
else:
print('用户名和密码不正确')
日志模块logging(只需要CV)
1、如何理解日志
所谓日志就是一个用来记录我们行为举止的代码,类似以前的史官,我们在平时的使用中并不要求自己可以写出来,会用别人的代码并且会改就可以了。因为以后会使用整合更好的模块来使用。
2、日志的五种级别
logging模块日志级别有DEBUG < INFO < WARNING < ERROR < CRITICAL 五种。
DEBUG - 调试模式,应用场景是问题诊断;
INFO - 通常只记录程序中一般事件的信息,用于确认工作一切正常;
WARNING - 打印警告信息,系统还在正常运行;
ERROR - 错误导致某些功能不能正常运行时记录的信息;
CRITICAL - 当发生严重错误,导致应用程序不能继续运行时记录的信息。
3、组成部分
- logger:提供记录日志的方法。
- handler:选择日志的输出地方(一个logger添加多个handler)。
- filter:给用户提供更加细粒度的控制日志的输出内容。
- format:用户格式化输出日志的信息。
4、配置方法
1.基础配置
logging.basicConfig(filename="config.log",
filemode="w",
format="%(asctime)s-%(name)s-%(levelname)s-%(message)s",
level=logging.INFO)
2.使用配置文件的方式
fileConfig(filename,defaults=None,disable_existing_loggers=Ture )
3.使用一个字典方式来写配置信息
使用dictConfig(dict,defaults=None, disable_existing_loggers=Ture )函数
4、日志输出
-
StreamHandler
logging.StreamHandler:日志输出到流,可以是sys.stderr,sys.stdout或者文件
-
FileHandler
logging.FileHandler:日志输出到文件
-
BaseRotatingHandler
logging.handlers.BaseRotatingHandler:基本的日志回滚方式
-
RotatingHandler
logging.handlers.RotatingHandler:日志回滚方式,支持日志文件最大数量和日志文件回滚
5、format常用格式说明
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
6、日志的执行过程
1、产生日志
2、过滤日志
这里我们需要注意,通常来说我们会在产生日志的时候设置需要产生的日志。其他不需要的日志就不会生成,所以基本用不到这个模块
3、输出日志
4、日志格式
5、字段解释
# 字段解释
filename:日志文件名的prefix;
when:是一个字符串,用于描述滚动周期的基本单位,字符串的值及意义如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
interval: 滚动周期,单位有when指定,比如:when=’D’,interval=1,表示每天产生一个日志文件
backupCount: 表示日志文件的保留个数
举例:
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('写了半天 好累啊 好热啊')
6、日志配置字典
通常来说我们都是使用日志字典的形式来达成功能的(功能多又方便,谁不喜欢呢)。这里也是跟之前的说的一样,会用就好,不需要了解。
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'
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,
# 这里两个参数的意思是一个日志文件最多写5M,最多可以存在五个不同的日志文件,但是当数量达到五个之后就会出现最早的那个会被删除,
# 然后再产生一个新的文件(类似于覆盖了最早的那个文件)
'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) # 自动加载字典中的配置
# logger1 = logging.getLogger('购物车记录')
# logger1.warning('尊敬的VIP客户 晚上好 您又来啦')
# logger1 = logging.getLogger('注册记录')
# logger1.debug('jason注册成功')
logger1 = logging.getLogger('红浪漫顾客消费记录')
# 当这里的getLogger内部的参数如果字典中没有,就会自动使用字典中名称为空的那个模版来执行
logger1.debug('慢男 猛男 骚男')
第三方模块的下载与安装
之前学习的模块都是内置的模块,不需要安装的,直接拿来使用
但是,内置模块不能够满足我们日常的开发需求,有时候呢需要借助于一些第三方的模块(别人开发的,下载使用)
如何下载与使用第三方模块: pip 命令是有Python解释器提供的
pip install 模块名 # 默认装的是最新的版本
pip3.8 install django==版本名
# pip list 查看解释器中已经安装了哪些模块
为了加快下载的速度,我们把默认的官网源修改成我们国内的源
"""换源"""
国内的源:
豆瓣:http://pypi.douban.com/simple/
阿里云:http://mirrors.aliyun.com/pypi/simple/
华为云:https://repo.huaweicloud.com/repository/pypi/simple
清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
中科大:https://pypi.mirrors.ustc.edu.cn/simple/
换源的方法:
pip install django # 默认使用的是python官方的
pip3.8 install numpy -i http://mirrors.aliyun.com/pypi/simple/ # 临时换源
永久换源:
##### Windows
-1 在文件地址栏输入:%APPDATA% 回车,快速进入 C:\Users\电脑用户\AppData\Roaming 文件夹中
-2 新建 pip 文件夹并
-3 在文件夹中新建 pip.ini 配置文件
-4 配置文件写入:
如果想换源就直接把源的路径换了就可以了
'''
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
use-mirrors =true
mirrors =https://mirrors.aliyun.com/pypi/simple
trusted-host =mirrors.aliyun.com
'''
# 以后再命令行中,下载模块,就会走国内源了
pip3.8 install django==3.2.12