常用的内置模块

时间模块

这个模块我们就比较熟悉了,之前学的时候调用过内部的几个功能

三种时间表现形式

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
posted @ 2023-09-21 21:28  jntmwl  阅读(15)  评论(0编辑  收藏  举报